summaryrefslogtreecommitdiff
path: root/js/src/vm
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-11-26 13:37:09 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-11-26 13:37:09 +0100
commit185a9a750878ed1d9705fbd162dbfe9bf2e4ea0c (patch)
tree9b83879173624e3dcb5ba6d1404fb89f2c47cb66 /js/src/vm
parente8c40b0bc2aa25b9f85ddbe3949c296311cc0f3f (diff)
downloaduxp-185a9a750878ed1d9705fbd162dbfe9bf2e4ea0c.tar.gz
Issue #1302 - Add self-hosted implementation for string regex .matchAll
This resolves #1302.
Diffstat (limited to 'js/src/vm')
-rw-r--r--js/src/vm/CommonPropertyNames.h1
-rw-r--r--js/src/vm/GlobalObject.cpp79
-rw-r--r--js/src/vm/GlobalObject.h8
-rw-r--r--js/src/vm/SelfHosting.cpp23
4 files changed, 55 insertions, 56 deletions
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index 4ae49d5771..99cb02e586 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -282,6 +282,7 @@
macro(RegExpFlagsGetter, RegExpFlagsGetter, "RegExpFlagsGetter") \
macro(RegExpMatcher, RegExpMatcher, "RegExpMatcher") \
macro(RegExpSearcher, RegExpSearcher, "RegExpSearcher") \
+ macro(RegExpStringIterator, RegExpStringIterator, "RegExp String Iterator") \
macro(RegExpTester, RegExpTester, "RegExpTester") \
macro(RegExp_prototype_Exec, RegExp_prototype_Exec, "RegExp_prototype_Exec") \
macro(Reify, Reify, "Reify") \
diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp
index 85707e1c60..013208f666 100644
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -468,62 +468,29 @@ GlobalObject::initSelfHostingBuiltins(JSContext* cx, Handle<GlobalObject*> globa
return false;
}
- RootedValue std_isConcatSpreadable(cx);
- std_isConcatSpreadable.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::isConcatSpreadable));
- if (!JS_DefineProperty(cx, global, "std_isConcatSpreadable", std_isConcatSpreadable,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- // Define a top-level property 'std_iterator' with the name of the method
- // used by for-of loops to create an iterator.
- RootedValue std_iterator(cx);
- std_iterator.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::iterator));
- if (!JS_DefineProperty(cx, global, "std_iterator", std_iterator,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_match(cx);
- std_match.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::match));
- if (!JS_DefineProperty(cx, global, "std_match", std_match,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_replace(cx);
- std_replace.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::replace));
- if (!JS_DefineProperty(cx, global, "std_replace", std_replace,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_search(cx);
- std_search.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::search));
- if (!JS_DefineProperty(cx, global, "std_search", std_search,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_species(cx);
- std_species.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::species));
- if (!JS_DefineProperty(cx, global, "std_species", std_species,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_split(cx);
- std_split.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::split));
- if (!JS_DefineProperty(cx, global, "std_split", std_split,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
+ struct SymbolAndName {
+ JS::SymbolCode code;
+ const char* name;
+ };
+
+ SymbolAndName wellKnownSymbols[] = {
+ {JS::SymbolCode::isConcatSpreadable, "std_isConcatSpreadable"},
+ {JS::SymbolCode::iterator, "std_iterator"},
+ {JS::SymbolCode::match, "std_match"},
+ {JS::SymbolCode::matchAll, "std_matchAll"},
+ {JS::SymbolCode::replace, "std_replace"},
+ {JS::SymbolCode::search, "std_search"},
+ {JS::SymbolCode::species, "std_species"},
+ {JS::SymbolCode::split, "std_split"},
+ };
+
+ RootedValue symVal(cx);
+ for (const auto& sym : wellKnownSymbols) {
+ symVal.setSymbol(cx->wellKnownSymbols().get(sym.code));
+ if (!JS_DefineProperty(cx, global, sym.name, symVal,
+ JSPROP_PERMANENT | JSPROP_READONLY)) {
+ return false;
+ }
}
return InitBareBuiltinCtor(cx, global, JSProto_Array) &&
diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h
index 5aacfc5dcd..9179abbb7d 100644
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -93,6 +93,7 @@ class GlobalObject : public NativeObject
ITERATOR_PROTO,
ARRAY_ITERATOR_PROTO,
STRING_ITERATOR_PROTO,
+ REGEXP_STRING_ITERATOR_PROTO,
LEGACY_GENERATOR_OBJECT_PROTO,
STAR_GENERATOR_OBJECT_PROTO,
STAR_GENERATOR_FUNCTION_PROTO,
@@ -583,6 +584,12 @@ class GlobalObject : public NativeObject
}
static NativeObject*
+ getOrCreateRegExpStringIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, REGEXP_STRING_ITERATOR_PROTO,
+ initRegExpStringIteratorProto));
+ }
+
+ static NativeObject*
getOrCreateLegacyGeneratorObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
return MaybeNativeObject(getOrCreateObject(cx, global, LEGACY_GENERATOR_OBJECT_PROTO,
initLegacyGeneratorProto));
@@ -767,6 +774,7 @@ class GlobalObject : public NativeObject
static bool initIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
static bool initArrayIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
static bool initStringIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
+ static bool initRegExpStringIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
// Implemented in vm/GeneratorObject.cpp.
static bool initLegacyGeneratorProto(JSContext* cx, Handle<GlobalObject*> global);
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index 8334104652..ffd707b147 100644
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -857,6 +857,24 @@ intrinsic_NewStringIterator(JSContext* cx, unsigned argc, Value* vp)
}
static bool
+intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc, Value* vp)
+{
+ CallArgs args = CallArgsFromVp(argc, vp);
+ MOZ_ASSERT(args.length() == 0);
+
+ RootedObject proto(cx, GlobalObject::getOrCreateRegExpStringIteratorPrototype(cx, cx->global()));
+ if (!proto)
+ return false;
+
+ JSObject* obj = NewObjectWithGivenProto(cx, &RegExpStringIteratorObject::class_, proto);
+ if (!obj)
+ return false;
+
+ args.rval().setObject(*obj);
+ return true;
+}
+
+static bool
intrinsic_SetCanonicalName(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
@@ -2288,6 +2306,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_INLINABLE_FN("GuardToStringIterator",
intrinsic_GuardToBuiltin<StringIteratorObject>, 1,0,
IntrinsicGuardToStringIterator),
+ JS_FN("GuardToRegExpStringIterator",
+ intrinsic_GuardToBuiltin<RegExpStringIteratorObject>, 1,0),
JS_FN("_CreateMapIterationResultPair", intrinsic_CreateMapIterationResultPair, 0, 0),
JS_INLINABLE_FN("_GetNextMapEntryForIterator", intrinsic_GetNextMapEntryForIterator, 2,0,
@@ -2305,6 +2325,9 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("NewStringIterator", intrinsic_NewStringIterator, 0,0),
JS_FN("CallStringIteratorMethodIfWrapped",
CallNonGenericSelfhostedMethod<Is<StringIteratorObject>>, 2,0),
+ JS_FN("NewRegExpStringIterator", intrinsic_NewRegExpStringIterator, 0,0),
+ JS_FN("CallRegExpStringIteratorMethodIfWrapped",
+ CallNonGenericSelfhostedMethod<Is<RegExpStringIteratorObject>>, 2,0),
JS_FN("IsStarGeneratorObject",
intrinsic_IsInstanceOfBuiltin<StarGeneratorObject>, 1,0),