65a97a3ce7121c54b884a18f17eba3b39027310c
[WebKit-https.git] / Source / JavaScriptCore / runtime / RegExpObject.h
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2003, 2007-2008, 2012, 2016 Apple Inc. All Rights Reserved.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  */
20
21 #pragma once
22
23 #include "JSObject.h"
24 #include "RegExp.h"
25 #include "ThrowScope.h"
26
27 namespace JSC {
28     
29 class RegExpObject : public JSNonFinalObject {
30 public:
31     typedef JSNonFinalObject Base;
32     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
33
34     static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
35     {
36         RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp);
37         object->finishCreation(vm);
38         return object;
39     }
40
41     void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
42     RegExp* regExp() const { return m_regExp.get(); }
43
44     bool setLastIndex(ExecState* exec, size_t lastIndex)
45     {
46         VM& vm = exec->vm();
47         auto scope = DECLARE_THROW_SCOPE(vm);
48
49         if (LIKELY(m_lastIndexIsWritable)) {
50             m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
51             return true;
52         }
53         throwTypeError(exec, scope, ReadonlyPropertyWriteError);
54         return false;
55     }
56     bool setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
57     {
58         VM& vm = exec->vm();
59         auto scope = DECLARE_THROW_SCOPE(vm);
60
61         if (LIKELY(m_lastIndexIsWritable)) {
62             m_lastIndex.set(exec->vm(), this, lastIndex);
63             return true;
64         }
65
66         if (shouldThrow)
67             throwTypeError(exec, scope, ReadonlyPropertyWriteError);
68         return false;
69     }
70     JSValue getLastIndex() const
71     {
72         return m_lastIndex.get();
73     }
74
75     bool test(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { return !!match(exec, globalObject, string); }
76     bool testInline(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { return !!matchInline(exec, globalObject, string); }
77     JSValue exec(ExecState*, JSGlobalObject*, JSString*);
78     JSValue execInline(ExecState*, JSGlobalObject*, JSString*);
79     MatchResult match(ExecState*, JSGlobalObject*, JSString*);
80     JSValue matchGlobal(ExecState*, JSGlobalObject*, JSString*);
81
82     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
83     static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
84
85     DECLARE_EXPORT_INFO;
86
87     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
88     {
89         return Structure::create(vm, globalObject, prototype, TypeInfo(RegExpObjectType, StructureFlags), info());
90     }
91
92     static ptrdiff_t offsetOfLastIndex()
93     {
94         return OBJECT_OFFSETOF(RegExpObject, m_lastIndex);
95     }
96
97     static ptrdiff_t offsetOfLastIndexIsWritable()
98     {
99         return OBJECT_OFFSETOF(RegExpObject, m_lastIndexIsWritable);
100     }
101
102     static unsigned advanceStringUnicode(String, unsigned length, unsigned currentIndex);
103
104 protected:
105     JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
106     JS_EXPORT_PRIVATE void finishCreation(VM&);
107
108     static void visitChildren(JSCell*, SlotVisitor&);
109
110     JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
111     JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
112     JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
113     JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
114     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
115
116 private:
117     MatchResult matchInline(ExecState*, JSGlobalObject*, JSString*);
118
119     WriteBarrier<RegExp> m_regExp;
120     WriteBarrier<Unknown> m_lastIndex;
121     bool m_lastIndexIsWritable;
122 };
123
124 RegExpObject* asRegExpObject(JSValue);
125
126 inline RegExpObject* asRegExpObject(JSValue value)
127 {
128     ASSERT(asObject(value)->inherits(RegExpObject::info()));
129     return static_cast<RegExpObject*>(asObject(value));
130 }
131
132 } // namespace JSC