13512742ab7f91c1e7316bb11996ac4a0a0e3afa
[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 "Reject.h"
26 #include "ThrowScope.h"
27
28 namespace JSC {
29     
30 class RegExpObject : public JSNonFinalObject {
31 public:
32     typedef JSNonFinalObject Base;
33     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
34
35     static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
36     {
37         RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp);
38         object->finishCreation(vm);
39         return object;
40     }
41
42     void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
43     RegExp* regExp() const { return m_regExp.get(); }
44
45     bool setLastIndex(ExecState* exec, size_t lastIndex)
46     {
47         VM& vm = exec->vm();
48         auto scope = DECLARE_THROW_SCOPE(vm);
49
50         if (LIKELY(m_lastIndexIsWritable)) {
51             m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
52             return true;
53         }
54         throwTypeError(exec, scope, ASCIILiteral(ReadonlyPropertyWriteError));
55         return false;
56     }
57     bool setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
58     {
59         VM& vm = exec->vm();
60         auto scope = DECLARE_THROW_SCOPE(vm);
61
62         if (LIKELY(m_lastIndexIsWritable)) {
63             m_lastIndex.set(vm, this, lastIndex);
64             return true;
65         }
66
67         return reject(exec, scope, shouldThrow, ASCIILiteral(ReadonlyPropertyWriteError));
68     }
69     JSValue getLastIndex() const
70     {
71         return m_lastIndex.get();
72     }
73
74     bool test(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { return !!match(exec, globalObject, string); }
75     bool testInline(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { return !!matchInline(exec, globalObject, string); }
76     JSValue exec(ExecState*, JSGlobalObject*, JSString*);
77     JSValue execInline(ExecState*, JSGlobalObject*, JSString*);
78     MatchResult match(ExecState*, JSGlobalObject*, JSString*);
79     JSValue matchGlobal(ExecState*, JSGlobalObject*, JSString*);
80
81     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
82     static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
83
84     DECLARE_EXPORT_INFO;
85
86     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
87     {
88         return Structure::create(vm, globalObject, prototype, TypeInfo(RegExpObjectType, StructureFlags), info());
89     }
90
91     static ptrdiff_t offsetOfLastIndex()
92     {
93         return OBJECT_OFFSETOF(RegExpObject, m_lastIndex);
94     }
95
96     static ptrdiff_t offsetOfLastIndexIsWritable()
97     {
98         return OBJECT_OFFSETOF(RegExpObject, m_lastIndexIsWritable);
99     }
100
101     static unsigned advanceStringUnicode(String, unsigned length, unsigned currentIndex);
102
103 protected:
104     JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
105     JS_EXPORT_PRIVATE void finishCreation(VM&);
106
107     static void visitChildren(JSCell*, SlotVisitor&);
108
109     JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
110     JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
111     JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
112     JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
113     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
114
115 private:
116     MatchResult matchInline(ExecState*, JSGlobalObject*, JSString*);
117
118     WriteBarrier<RegExp> m_regExp;
119     WriteBarrier<Unknown> m_lastIndex;
120     bool m_lastIndexIsWritable;
121 };
122
123 RegExpObject* asRegExpObject(JSValue);
124
125 inline RegExpObject* asRegExpObject(JSValue value)
126 {
127     ASSERT(asObject(value)->inherits(RegExpObject::info()));
128     return static_cast<RegExpObject*>(asObject(value));
129 }
130
131 } // namespace JSC