summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/runtime/RegExpMatchesArray.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/runtime/RegExpMatchesArray.h')
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.h207
1 files changed, 101 insertions, 106 deletions
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
index 67fdcb6e1..64ceccb8f 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,124 +17,119 @@
*
*/
-#ifndef RegExpMatchesArray_h
-#define RegExpMatchesArray_h
+#pragma once
+#include "ButterflyInlines.h"
+#include "GCDeferralContextInlines.h"
#include "JSArray.h"
+#include "JSCInlines.h"
#include "JSGlobalObject.h"
+#include "RegExpInlines.h"
#include "RegExpObject.h"
namespace JSC {
- class RegExpMatchesArray : public JSArray {
- private:
- RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
-
- enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll };
-
- public:
- typedef JSArray Base;
-
- static RegExpMatchesArray* create(ExecState*, JSString*, RegExp*, MatchResult);
-
- JSString* leftContext(ExecState*);
- JSString* rightContext(ExecState*);
-
- DECLARE_INFO;
-
- static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayWithSlowPutArrayStorage);
- }
-
- static void visitChildren(JSCell*, SlotVisitor&);
-
- protected:
- void finishCreation(VM&);
-
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
-
- private:
- ALWAYS_INLINE void reifyAllPropertiesIfNecessary(ExecState* exec)
- {
- if (m_state != ReifiedAll)
- reifyAllProperties(exec);
- }
-
- ALWAYS_INLINE void reifyMatchPropertyIfNecessary(ExecState* exec)
- {
- if (m_state == ReifiedNone)
- reifyMatchProperty(exec);
- }
-
- static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
- thisObject->reifyAllPropertiesIfNecessary(exec);
- return JSArray::getOwnPropertySlot(thisObject, exec, propertyName, slot);
- }
+static const PropertyOffset RegExpMatchesArrayIndexPropertyOffset = 100;
+static const PropertyOffset RegExpMatchesArrayInputPropertyOffset = 101;
+
+ALWAYS_INLINE JSArray* tryCreateUninitializedRegExpMatchesArray(VM& vm, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
+{
+ unsigned vectorLength = initialLength;
+ if (vectorLength > MAX_STORAGE_VECTOR_LENGTH)
+ return 0;
+
+ void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
+ if (!temp)
+ return nullptr;
+ Butterfly* butterfly = Butterfly::fromBase(temp, 0, structure->outOfLineCapacity());
+ butterfly->setVectorLength(vectorLength);
+ butterfly->setPublicLength(initialLength);
+
+ for (unsigned i = initialLength; i < vectorLength; ++i)
+ butterfly->contiguous()[i].clear();
+
+ return JSArray::createWithButterfly(vm, deferralContext, structure, butterfly);
+}
- static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
- if (propertyName)
- thisObject->reifyAllPropertiesIfNecessary(exec);
+ALWAYS_INLINE JSArray* createRegExpMatchesArray(
+ VM& vm, JSGlobalObject* globalObject, JSString* input, const String& inputValue,
+ RegExp* regExp, unsigned startOffset, MatchResult& result)
+{
+ Vector<int, 32> subpatternResults;
+ int position = regExp->matchInline(vm, inputValue, startOffset, subpatternResults);
+ if (position == -1) {
+ result = MatchResult::failed();
+ return nullptr;
+ }
+
+ result.start = position;
+ result.end = subpatternResults[1];
+
+ JSArray* array;
+
+ // FIXME: This should handle array allocation errors gracefully.
+ // https://bugs.webkit.org/show_bug.cgi?id=155144
+
+ auto setProperties = [&] () {
+ array->putDirect(vm, RegExpMatchesArrayIndexPropertyOffset, jsNumber(result.start));
+ array->putDirect(vm, RegExpMatchesArrayInputPropertyOffset, input);
+ };
+
+ unsigned numSubpatterns = regExp->numSubpatterns();
+
+ GCDeferralContext deferralContext(vm.heap);
+
+ if (UNLIKELY(globalObject->isHavingABadTime())) {
+ array = JSArray::tryCreateForInitializationPrivate(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
+ // FIXME: we should probably throw an out of memory error here, but
+ // when making this change we should check that all clients of this
+ // function will correctly handle an exception being thrown from here.
+ // https://bugs.webkit.org/show_bug.cgi?id=169786
+ RELEASE_ASSERT(array);
+
+ setProperties();
+
+ array->initializeIndexWithoutBarrier(0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start));
+
+ for (unsigned i = 1; i <= numSubpatterns; ++i) {
+ int start = subpatternResults[2 * i];
+ JSValue value;
+ if (start >= 0)
+ value = JSRopeString::createSubstringOfResolved(vm, &deferralContext, input, start, subpatternResults[2 * i + 1] - start);
else
- thisObject->reifyMatchPropertyIfNecessary(exec);
- return JSArray::getOwnPropertySlotByIndex(thisObject, exec, propertyName, slot);
- }
-
- static void put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue v, PutPropertySlot& slot)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- thisObject->reifyAllPropertiesIfNecessary(exec);
- JSArray::put(thisObject, exec, propertyName, v, slot);
+ value = jsUndefined();
+ array->initializeIndexWithoutBarrier(i, value);
}
+ } else {
+ array = tryCreateUninitializedRegExpMatchesArray(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
+ RELEASE_ASSERT(array);
- static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v, bool shouldThrow)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- thisObject->reifyAllPropertiesIfNecessary(exec);
- JSArray::putByIndex(thisObject, exec, propertyName, v, shouldThrow);
- }
-
- static bool deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- thisObject->reifyAllPropertiesIfNecessary(exec);
- return JSArray::deleteProperty(thisObject, exec, propertyName);
- }
-
- static bool deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- thisObject->reifyAllPropertiesIfNecessary(exec);
- return JSArray::deletePropertyByIndex(thisObject, exec, propertyName);
- }
-
- static void getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
- thisObject->reifyAllPropertiesIfNecessary(exec);
- JSArray::getOwnPropertyNames(thisObject, exec, arr, mode);
- }
+ setProperties();
+
+ // Now the object is safe to scan by GC.
- static bool defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
- {
- RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
- thisObject->reifyAllPropertiesIfNecessary(exec);
- return JSArray::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
+ array->initializeIndexWithoutBarrier(0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start), ArrayWithContiguous);
+
+ for (unsigned i = 1; i <= numSubpatterns; ++i) {
+ int start = subpatternResults[2 * i];
+ JSValue value;
+ if (start >= 0)
+ value = JSRopeString::createSubstringOfResolved(vm, &deferralContext, input, start, subpatternResults[2 * i + 1] - start);
+ else
+ value = jsUndefined();
+ array->initializeIndexWithoutBarrier(i, value, ArrayWithContiguous);
}
+ }
+ return array;
+}
- void reifyAllProperties(ExecState*);
- void reifyMatchProperty(ExecState*);
-
- WriteBarrier<JSString> m_input;
- WriteBarrier<RegExp> m_regExp;
- MatchResult m_result;
- ReifiedState m_state;
-};
-
+inline JSArray* createRegExpMatchesArray(ExecState* exec, JSGlobalObject* globalObject, JSString* string, RegExp* regExp, unsigned startOffset)
+{
+ MatchResult ignoredResult;
+ return createRegExpMatchesArray(globalObject->vm(), globalObject, string, string->value(exec), regExp, startOffset, ignoredResult);
}
+JSArray* createEmptyRegExpMatchesArray(JSGlobalObject*, JSString*, RegExp*);
+Structure* createRegExpMatchesArrayStructure(VM&, JSGlobalObject*);
+Structure* createRegExpMatchesArraySlowPutStructure(VM&, JSGlobalObject*);
-#endif // RegExpMatchesArray_h
+} // namespace JSC