Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_OBJECTS_JS_REGEXP_H_
6 : #define V8_OBJECTS_JS_REGEXP_H_
7 :
8 : #include "src/objects/js-array.h"
9 :
10 : // Has to be the last include (doesn't have include guards):
11 : #include "src/objects/object-macros.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : // Regular expressions
17 : // The regular expression holds a single reference to a FixedArray in
18 : // the kDataOffset field.
19 : // The FixedArray contains the following data:
20 : // - tag : type of regexp implementation (not compiled yet, atom or irregexp)
21 : // - reference to the original source string
22 : // - reference to the original flag string
23 : // If it is an atom regexp
24 : // - a reference to a literal string to search for
25 : // If it is an irregexp regexp:
26 : // - a reference to code for Latin1 inputs (bytecode or compiled), or a smi
27 : // used for tracking the last usage (used for regexp code flushing).
28 : // - a reference to code for UC16 inputs (bytecode or compiled), or a smi
29 : // used for tracking the last usage (used for regexp code flushing).
30 : // - max number of registers used by irregexp implementations.
31 : // - number of capture registers (output values) of the regexp.
32 : class JSRegExp : public JSObject {
33 : public:
34 : // Meaning of Type:
35 : // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
36 : // ATOM: A simple string to match against using an indexOf operation.
37 : // IRREGEXP: Compiled with Irregexp.
38 : enum Type { NOT_COMPILED, ATOM, IRREGEXP };
39 : enum Flag {
40 : kNone = 0,
41 : kGlobal = 1 << 0,
42 : kIgnoreCase = 1 << 1,
43 : kMultiline = 1 << 2,
44 : kSticky = 1 << 3,
45 : kUnicode = 1 << 4,
46 : kDotAll = 1 << 5,
47 : // Update FlagCount when adding new flags.
48 : };
49 : typedef base::Flags<Flag> Flags;
50 :
51 418575 : static int FlagCount() { return FLAG_harmony_regexp_dotall ? 6 : 5; }
52 :
53 : DECL_ACCESSORS(data, Object)
54 : DECL_ACCESSORS(flags, Object)
55 : DECL_ACCESSORS(last_index, Object)
56 : DECL_ACCESSORS(source, Object)
57 :
58 : V8_EXPORT_PRIVATE static MaybeHandle<JSRegExp> New(Handle<String> source,
59 : Flags flags);
60 : static Handle<JSRegExp> Copy(Handle<JSRegExp> regexp);
61 :
62 : static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
63 : Handle<String> source, Flags flags);
64 : static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
65 : Handle<String> source,
66 : Handle<String> flags_string);
67 :
68 : inline Type TypeTag();
69 : // Number of captures (without the match itself).
70 : inline int CaptureCount();
71 : inline Flags GetFlags();
72 : inline String* Pattern();
73 : inline Object* CaptureNameMap();
74 : inline Object* DataAt(int index);
75 : // Set implementation data after the object has been prepared.
76 : inline void SetDataAt(int index, Object* value);
77 :
78 : static int code_index(bool is_latin1) {
79 1664217 : if (is_latin1) {
80 : return kIrregexpLatin1CodeIndex;
81 : } else {
82 : return kIrregexpUC16CodeIndex;
83 : }
84 : }
85 :
86 : DECL_CAST(JSRegExp)
87 :
88 : // Dispatched behavior.
89 : DECL_PRINTER(JSRegExp)
90 : DECL_VERIFIER(JSRegExp)
91 :
92 : static const int kDataOffset = JSObject::kHeaderSize;
93 : static const int kSourceOffset = kDataOffset + kPointerSize;
94 : static const int kFlagsOffset = kSourceOffset + kPointerSize;
95 : static const int kSize = kFlagsOffset + kPointerSize;
96 : static const int kLastIndexOffset = kSize; // In-object field.
97 :
98 : // Indices in the data array.
99 : static const int kTagIndex = 0;
100 : static const int kSourceIndex = kTagIndex + 1;
101 : static const int kFlagsIndex = kSourceIndex + 1;
102 : static const int kDataIndex = kFlagsIndex + 1;
103 : // The data fields are used in different ways depending on the
104 : // value of the tag.
105 : // Atom regexps (literal strings).
106 : static const int kAtomPatternIndex = kDataIndex;
107 :
108 : static const int kAtomDataSize = kAtomPatternIndex + 1;
109 :
110 : // Irregexp compiled code or bytecode for Latin1. If compilation
111 : // fails, this fields hold an exception object that should be
112 : // thrown if the regexp is used again.
113 : static const int kIrregexpLatin1CodeIndex = kDataIndex;
114 : // Irregexp compiled code or bytecode for UC16. If compilation
115 : // fails, this fields hold an exception object that should be
116 : // thrown if the regexp is used again.
117 : static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
118 : // Maximal number of registers used by either Latin1 or UC16.
119 : // Only used to check that there is enough stack space
120 : static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 2;
121 : // Number of captures in the compiled regexp.
122 : static const int kIrregexpCaptureCountIndex = kDataIndex + 3;
123 : // Maps names of named capture groups (at indices 2i) to their corresponding
124 : // (1-based) capture group indices (at indices 2i + 1).
125 : static const int kIrregexpCaptureNameMapIndex = kDataIndex + 4;
126 :
127 : static const int kIrregexpDataSize = kIrregexpCaptureNameMapIndex + 1;
128 :
129 : // In-object fields.
130 : static const int kLastIndexFieldIndex = 0;
131 : static const int kInObjectFieldCount = 1;
132 :
133 : // The uninitialized value for a regexp code object.
134 : static const int kUninitializedValue = -1;
135 : };
136 :
137 : DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
138 :
139 : // JSRegExpResult is just a JSArray with a specific initial map.
140 : // This initial map adds in-object properties for "index" and "input"
141 : // properties, as assigned by RegExp.prototype.exec, which allows
142 : // faster creation of RegExp exec results.
143 : // This class just holds constants used when creating the result.
144 : // After creation the result must be treated as a JSArray in all regards.
145 : class JSRegExpResult : public JSArray {
146 : public:
147 : // Offsets of object fields.
148 : static const int kIndexOffset = JSArray::kSize;
149 : static const int kInputOffset = kIndexOffset + kPointerSize;
150 : static const int kSize = kInputOffset + kPointerSize;
151 : // Indices of in-object properties.
152 : static const int kIndexIndex = 0;
153 : static const int kInputIndex = 1;
154 :
155 : private:
156 : DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
157 : };
158 :
159 : } // namespace internal
160 : } // namespace v8
161 :
162 : #include "src/objects/object-macros-undef.h"
163 :
164 : #endif // V8_OBJECTS_JS_REGEXP_H_
|