OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 10 matching lines...) Expand all Loading... |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 #include "ast.h" | 29 #include "ast.h" |
30 #include "bytecodes-irregexp.h" | 30 #include "bytecodes-irregexp.h" |
31 #include "assembler-irregexp.h" | |
32 #include "assembler-irregexp-inl.h" | |
33 #include "regexp-macro-assembler.h" | 31 #include "regexp-macro-assembler.h" |
34 #include "regexp-macro-assembler-irregexp.h" | 32 #include "regexp-macro-assembler-irregexp.h" |
| 33 #include "regexp-macro-assembler-irregexp-inl.h" |
35 | 34 |
36 | 35 |
37 namespace v8 { namespace internal { | 36 namespace v8 { namespace internal { |
38 | 37 |
39 | 38 |
| 39 RegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Vector<byte> buffer) |
| 40 : buffer_(buffer), |
| 41 pc_(0), |
| 42 own_buffer_(false) { |
| 43 } |
| 44 |
| 45 |
40 RegExpMacroAssemblerIrregexp::~RegExpMacroAssemblerIrregexp() { | 46 RegExpMacroAssemblerIrregexp::~RegExpMacroAssemblerIrregexp() { |
41 } | 47 } |
42 | 48 |
43 | 49 |
44 RegExpMacroAssemblerIrregexp::IrregexpImplementation | 50 RegExpMacroAssemblerIrregexp::IrregexpImplementation |
45 RegExpMacroAssemblerIrregexp::Implementation() { | 51 RegExpMacroAssemblerIrregexp::Implementation() { |
46 return kBytecodeImplementation; | 52 return kBytecodeImplementation; |
47 } | 53 } |
48 | 54 |
49 | 55 |
50 void RegExpMacroAssemblerIrregexp::Bind(Label* l) { | 56 void RegExpMacroAssemblerIrregexp::Bind(Label* l) { |
51 assembler_->Bind(l); | 57 ASSERT(!l->is_bound()); |
| 58 if (l->is_linked()) { |
| 59 int pos = l->pos(); |
| 60 while (pos != 0) { |
| 61 int fixup = pos; |
| 62 pos = Load32(buffer_.start() + fixup); |
| 63 Store32(buffer_.start() + fixup, pc_); |
| 64 } |
| 65 } |
| 66 l->bind_to(pc_); |
52 } | 67 } |
53 | 68 |
54 | 69 |
55 void RegExpMacroAssemblerIrregexp::EmitOrLink(Label* l) { | 70 void RegExpMacroAssemblerIrregexp::EmitOrLink(Label* l) { |
56 assembler_->EmitOrLink(l); | 71 if (l->is_bound()) { |
| 72 Emit32(l->pos()); |
| 73 } else { |
| 74 int pos = 0; |
| 75 if (l->is_linked()) { |
| 76 pos = l->pos(); |
| 77 } |
| 78 l->link_to(pc_); |
| 79 Emit32(pos); |
| 80 } |
57 } | 81 } |
58 | 82 |
59 | 83 |
60 void RegExpMacroAssemblerIrregexp::PopRegister(int register_index) { | 84 void RegExpMacroAssemblerIrregexp::PopRegister(int register_index) { |
61 assembler_->PopRegister(register_index); | 85 Emit(BC_POP_REGISTER); |
| 86 Emit(register_index); |
62 } | 87 } |
63 | 88 |
64 | 89 |
65 void RegExpMacroAssemblerIrregexp::PushRegister(int register_index) { | 90 void RegExpMacroAssemblerIrregexp::PushRegister(int register_index) { |
66 assembler_->PushRegister(register_index); | 91 ASSERT(register_index >= 0); |
| 92 Emit(BC_PUSH_REGISTER); |
| 93 Emit(register_index); |
67 } | 94 } |
68 | 95 |
69 | 96 |
70 void RegExpMacroAssemblerIrregexp::WriteCurrentPositionToRegister( | 97 void RegExpMacroAssemblerIrregexp::WriteCurrentPositionToRegister( |
71 int register_index) { | 98 int register_index) { |
72 assembler_->WriteCurrentPositionToRegister(register_index); | 99 ASSERT(register_index >= 0); |
| 100 Emit(BC_SET_REGISTER_TO_CP); |
| 101 Emit(register_index); |
| 102 Emit32(0); // Current position offset. |
73 } | 103 } |
74 | 104 |
75 | 105 |
76 void RegExpMacroAssemblerIrregexp::ReadCurrentPositionFromRegister( | 106 void RegExpMacroAssemblerIrregexp::ReadCurrentPositionFromRegister( |
77 int register_index) { | 107 int register_index) { |
78 assembler_->ReadCurrentPositionFromRegister(register_index); | 108 ASSERT(register_index >= 0); |
| 109 Emit(BC_SET_CP_TO_REGISTER); |
| 110 Emit(register_index); |
79 } | 111 } |
80 | 112 |
81 | 113 |
82 void RegExpMacroAssemblerIrregexp::WriteStackPointerToRegister( | 114 void RegExpMacroAssemblerIrregexp::WriteStackPointerToRegister( |
83 int register_index) { | 115 int register_index) { |
84 assembler_->WriteStackPointerToRegister(register_index); | 116 ASSERT(register_index >= 0); |
| 117 Emit(BC_SET_REGISTER_TO_SP); |
| 118 Emit(register_index); |
85 } | 119 } |
86 | 120 |
87 | 121 |
88 void RegExpMacroAssemblerIrregexp::ReadStackPointerFromRegister( | 122 void RegExpMacroAssemblerIrregexp::ReadStackPointerFromRegister( |
89 int register_index) { | 123 int register_index) { |
90 assembler_->ReadStackPointerFromRegister(register_index); | 124 ASSERT(register_index >= 0); |
| 125 Emit(BC_SET_SP_TO_REGISTER); |
| 126 Emit(register_index); |
91 } | 127 } |
92 | 128 |
93 | 129 |
94 void RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) { | 130 void RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) { |
95 assembler_->SetRegister(register_index, to); | 131 ASSERT(register_index >= 0); |
| 132 Emit(BC_SET_REGISTER); |
| 133 Emit(register_index); |
| 134 Emit32(to); |
96 } | 135 } |
97 | 136 |
98 | 137 |
99 void RegExpMacroAssemblerIrregexp::AdvanceRegister(int register_index, int by) { | 138 void RegExpMacroAssemblerIrregexp::AdvanceRegister(int register_index, int by) { |
100 assembler_->AdvanceRegister(register_index, by); | 139 ASSERT(register_index >= 0); |
| 140 Emit(BC_ADVANCE_REGISTER); |
| 141 Emit(register_index); |
| 142 Emit32(by); |
101 } | 143 } |
102 | 144 |
103 | 145 |
104 void RegExpMacroAssemblerIrregexp::PopCurrentPosition() { | 146 void RegExpMacroAssemblerIrregexp::PopCurrentPosition() { |
105 assembler_->PopCurrentPosition(); | 147 Emit(BC_POP_CP); |
106 } | 148 } |
107 | 149 |
108 | 150 |
109 void RegExpMacroAssemblerIrregexp::PushCurrentPosition() { | 151 void RegExpMacroAssemblerIrregexp::PushCurrentPosition() { |
110 assembler_->PushCurrentPosition(); | 152 Emit(BC_PUSH_CP); |
| 153 Emit32(0); // Current position offset. |
111 } | 154 } |
112 | 155 |
113 | 156 |
114 void RegExpMacroAssemblerIrregexp::Backtrack() { | 157 void RegExpMacroAssemblerIrregexp::Backtrack() { |
115 assembler_->PopBacktrack(); | 158 Emit(BC_POP_BT); |
116 } | 159 } |
117 | 160 |
118 | 161 |
119 void RegExpMacroAssemblerIrregexp::GoTo(Label* l) { | 162 void RegExpMacroAssemblerIrregexp::GoTo(Label* l) { |
120 assembler_->GoTo(l); | 163 Emit(BC_GOTO); |
| 164 EmitOrLink(l); |
121 } | 165 } |
122 | 166 |
123 | 167 |
124 void RegExpMacroAssemblerIrregexp::PushBacktrack(Label* l) { | 168 void RegExpMacroAssemblerIrregexp::PushBacktrack(Label* l) { |
125 assembler_->PushBacktrack(l); | 169 Emit(BC_PUSH_BT); |
| 170 EmitOrLink(l); |
126 } | 171 } |
127 | 172 |
128 | 173 |
129 void RegExpMacroAssemblerIrregexp::Succeed() { | 174 void RegExpMacroAssemblerIrregexp::Succeed() { |
130 assembler_->Succeed(); | 175 Emit(BC_SUCCEED); |
131 } | 176 } |
132 | 177 |
133 | 178 |
134 void RegExpMacroAssemblerIrregexp::Fail() { | 179 void RegExpMacroAssemblerIrregexp::Fail() { |
135 assembler_->Fail(); | 180 Emit(BC_FAIL); |
136 } | 181 } |
137 | 182 |
138 | 183 |
139 void RegExpMacroAssemblerIrregexp::AdvanceCurrentPosition(int by) { | 184 void RegExpMacroAssemblerIrregexp::AdvanceCurrentPosition(int by) { |
140 assembler_->AdvanceCP(by); | 185 Emit(BC_ADVANCE_CP); |
| 186 Emit32(by); |
141 } | 187 } |
142 | 188 |
143 | 189 |
144 void RegExpMacroAssemblerIrregexp::CheckCurrentPosition( | 190 void RegExpMacroAssemblerIrregexp::CheckCurrentPosition( |
145 int register_index, | 191 int register_index, |
146 Label* on_equal) { | 192 Label* on_equal) { |
147 // TODO(erikcorry): Implement. | 193 // TODO(erikcorry): Implement. |
148 UNREACHABLE(); | 194 UNIMPLEMENTED(); |
149 } | 195 } |
150 | 196 |
151 | 197 |
152 void RegExpMacroAssemblerIrregexp::LoadCurrentCharacter(int cp_offset, | 198 void RegExpMacroAssemblerIrregexp::LoadCurrentCharacter(int cp_offset, |
153 Label* on_failure) { | 199 Label* on_failure) { |
154 assembler_->LoadCurrentChar(cp_offset, on_failure); | 200 Emit(BC_LOAD_CURRENT_CHAR); |
| 201 Emit32(cp_offset); |
| 202 EmitOrLink(on_failure); |
155 } | 203 } |
156 | 204 |
157 | 205 |
158 void RegExpMacroAssemblerIrregexp::CheckCharacterLT(uc16 limit, | 206 void RegExpMacroAssemblerIrregexp::CheckCharacterLT(uc16 limit, |
159 Label* on_less) { | 207 Label* on_less) { |
160 assembler_->CheckCharacterLT(limit, on_less); | 208 Emit(BC_CHECK_LT); |
| 209 Emit16(limit); |
| 210 EmitOrLink(on_less); |
161 } | 211 } |
162 | 212 |
163 | 213 |
164 void RegExpMacroAssemblerIrregexp::CheckCharacterGT(uc16 limit, | 214 void RegExpMacroAssemblerIrregexp::CheckCharacterGT(uc16 limit, |
165 Label* on_greater) { | 215 Label* on_greater) { |
166 assembler_->CheckCharacterGT(limit, on_greater); | 216 Emit(BC_CHECK_GT); |
| 217 Emit16(limit); |
| 218 EmitOrLink(on_greater); |
167 } | 219 } |
168 | 220 |
169 | 221 |
170 void RegExpMacroAssemblerIrregexp::CheckCharacter(uc16 c, Label* on_equal) { | 222 void RegExpMacroAssemblerIrregexp::CheckCharacter(uc16 c, Label* on_equal) { |
171 assembler_->CheckCharacter(c, on_equal); | 223 Emit(BC_CHECK_CHAR); |
| 224 Emit16(c); |
| 225 EmitOrLink(on_equal); |
172 } | 226 } |
173 | 227 |
174 | 228 |
175 void RegExpMacroAssemblerIrregexp::CheckNotCharacter(uc16 c, | 229 void RegExpMacroAssemblerIrregexp::CheckNotCharacter(uc16 c, |
176 Label* on_not_equal) { | 230 Label* on_not_equal) { |
177 assembler_->CheckNotCharacter(c, on_not_equal); | 231 Emit(BC_CHECK_NOT_CHAR); |
| 232 Emit16(c); |
| 233 EmitOrLink(on_not_equal); |
178 } | 234 } |
179 | 235 |
180 | 236 |
181 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterOr(uc16 c, | 237 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterOr( |
182 uc16 mask, | 238 uc16 c, |
183 Label* on_not_equal) { | 239 uc16 mask, |
184 assembler_->OrThenCheckNotCharacter(c, mask, on_not_equal); | 240 Label* on_not_equal) { |
| 241 Emit(BC_OR_CHECK_NOT_CHAR); |
| 242 Emit16(c); |
| 243 Emit16(mask); |
| 244 EmitOrLink(on_not_equal); |
185 } | 245 } |
186 | 246 |
187 | 247 |
188 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusOr( | 248 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusOr( |
189 uc16 c, | 249 uc16 c, |
190 uc16 mask, | 250 uc16 mask, |
191 Label* on_not_equal) { | 251 Label* on_not_equal) { |
192 assembler_->MinusOrThenCheckNotCharacter(c, mask, on_not_equal); | 252 Emit(BC_MINUS_OR_CHECK_NOT_CHAR); |
| 253 Emit16(c); |
| 254 Emit16(mask); |
| 255 EmitOrLink(on_not_equal); |
193 } | 256 } |
194 | 257 |
195 | 258 |
196 void RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg, | 259 void RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg, |
197 Label* on_not_equal) { | 260 Label* on_not_equal) { |
198 assembler_->CheckNotBackReference(start_reg, on_not_equal); | 261 Emit(BC_CHECK_NOT_BACK_REF); |
| 262 Emit(start_reg); |
| 263 EmitOrLink(on_not_equal); |
199 } | 264 } |
200 | 265 |
201 | 266 |
202 void RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase( | 267 void RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase( |
203 int start_reg, | 268 int start_reg, |
204 Label* on_not_equal) { | 269 Label* on_not_equal) { |
205 assembler_->CheckNotBackReferenceNoCase(start_reg, on_not_equal); | 270 Emit(BC_CHECK_NOT_BACK_REF_NO_CASE); |
| 271 Emit(start_reg); |
| 272 EmitOrLink(on_not_equal); |
206 } | 273 } |
207 | 274 |
208 | 275 |
209 void RegExpMacroAssemblerIrregexp::CheckNotRegistersEqual(int reg1, | 276 void RegExpMacroAssemblerIrregexp::CheckNotRegistersEqual(int reg1, |
210 int reg2, | 277 int reg2, |
211 Label* on_not_equal) { | 278 Label* on_not_equal) { |
212 assembler_->CheckNotRegistersEqual(reg1, reg2, on_not_equal); | 279 Emit(BC_CHECK_NOT_REGS_EQUAL); |
| 280 Emit(reg1); |
| 281 Emit(reg2); |
| 282 EmitOrLink(on_not_equal); |
213 } | 283 } |
214 | 284 |
215 | 285 |
216 void RegExpMacroAssemblerIrregexp::CheckBitmap(uc16 start, | 286 void RegExpMacroAssemblerIrregexp::CheckBitmap(uc16 start, |
217 Label* bitmap, | 287 Label* bitmap, |
218 Label* on_zero) { | 288 Label* on_zero) { |
219 assembler_->LookupMap1(start, bitmap, on_zero); | 289 UNIMPLEMENTED(); |
220 } | 290 } |
221 | 291 |
222 | 292 |
223 void RegExpMacroAssemblerIrregexp::DispatchHalfNibbleMap( | 293 void RegExpMacroAssemblerIrregexp::DispatchHalfNibbleMap( |
224 uc16 start, | 294 uc16 start, |
225 Label* half_nibble_map, | 295 Label* half_nibble_map, |
226 const Vector<Label*>& table) { | 296 const Vector<Label*>& table) { |
227 assembler_->LookupMap2(start, half_nibble_map, table); | 297 UNIMPLEMENTED(); |
228 } | 298 } |
229 | 299 |
230 | 300 |
231 void RegExpMacroAssemblerIrregexp::DispatchByteMap( | 301 void RegExpMacroAssemblerIrregexp::DispatchByteMap( |
232 uc16 start, | 302 uc16 start, |
233 Label* byte_map, | 303 Label* byte_map, |
234 const Vector<Label*>& table) { | 304 const Vector<Label*>& table) { |
235 assembler_->LookupMap8(start, byte_map, table); | 305 UNIMPLEMENTED(); |
236 } | 306 } |
237 | 307 |
238 | 308 |
239 void RegExpMacroAssemblerIrregexp::DispatchHighByteMap( | 309 void RegExpMacroAssemblerIrregexp::DispatchHighByteMap( |
240 byte start, | 310 byte start, |
241 Label* byte_map, | 311 Label* byte_map, |
242 const Vector<Label*>& table) { | 312 const Vector<Label*>& table) { |
243 assembler_->LookupHighMap8(start, byte_map, table); | 313 UNIMPLEMENTED(); |
244 } | 314 } |
245 | 315 |
246 | 316 |
247 void RegExpMacroAssemblerIrregexp::CheckCharacters( | 317 void RegExpMacroAssemblerIrregexp::CheckCharacters( |
248 Vector<const uc16> str, | 318 Vector<const uc16> str, |
249 int cp_offset, | 319 int cp_offset, |
250 Label* on_failure) { | 320 Label* on_failure) { |
251 for (int i = str.length() - 1; i >= 0; i--) { | 321 for (int i = str.length() - 1; i >= 0; i--) { |
252 assembler_->LoadCurrentChar(cp_offset + i, on_failure); | 322 Emit(BC_LOAD_CURRENT_CHAR); |
253 assembler_->CheckNotCharacter(str[i], on_failure); | 323 Emit32(cp_offset + i); |
| 324 EmitOrLink(on_failure); |
| 325 Emit(BC_CHECK_NOT_CHAR); |
| 326 Emit16(str[i]); |
| 327 EmitOrLink(on_failure); |
254 } | 328 } |
255 } | 329 } |
256 | 330 |
257 | 331 |
258 void RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index, | 332 void RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index, |
259 int comparand, | 333 int comparand, |
260 Label* if_less_than) { | 334 Label* on_less_than) { |
261 ASSERT(comparand >= 0 && comparand <= 65535); | 335 ASSERT(comparand >= 0 && comparand <= 65535); |
262 assembler_->CheckRegisterLT(register_index, comparand, if_less_than); | 336 Emit(BC_CHECK_REGISTER_LT); |
| 337 Emit(register_index); |
| 338 Emit16(comparand); |
| 339 EmitOrLink(on_less_than); |
263 } | 340 } |
264 | 341 |
265 | 342 |
266 void RegExpMacroAssemblerIrregexp::IfRegisterGE(int register_index, | 343 void RegExpMacroAssemblerIrregexp::IfRegisterGE(int register_index, |
267 int comparand, | 344 int comparand, |
268 Label* if_greater_or_equal) { | 345 Label* on_greater_or_equal) { |
269 ASSERT(comparand >= 0 && comparand <= 65535); | 346 ASSERT(comparand >= 0 && comparand <= 65535); |
270 assembler_->CheckRegisterGE(register_index, comparand, if_greater_or_equal); | 347 Emit(BC_CHECK_REGISTER_GE); |
| 348 Emit(register_index); |
| 349 Emit16(comparand); |
| 350 EmitOrLink(on_greater_or_equal); |
271 } | 351 } |
272 | 352 |
273 | 353 |
274 Handle<Object> RegExpMacroAssemblerIrregexp::GetCode() { | 354 Handle<Object> RegExpMacroAssemblerIrregexp::GetCode() { |
275 Handle<ByteArray> array = Factory::NewByteArray(assembler_->length()); | 355 Handle<ByteArray> array = Factory::NewByteArray(length()); |
276 assembler_->Copy(array->GetDataStartAddress()); | 356 Copy(array->GetDataStartAddress()); |
277 return array; | 357 return array; |
278 } | 358 } |
279 | 359 |
| 360 |
| 361 int RegExpMacroAssemblerIrregexp::length() { |
| 362 return pc_; |
| 363 } |
| 364 |
| 365 |
| 366 void RegExpMacroAssemblerIrregexp::Copy(Address a) { |
| 367 memcpy(a, buffer_.start(), length()); |
| 368 } |
| 369 |
| 370 |
| 371 void RegExpMacroAssemblerIrregexp::Expand() { |
| 372 bool old_buffer_was_our_own = own_buffer_; |
| 373 Vector<byte> old_buffer = buffer_; |
| 374 buffer_ = Vector<byte>::New(old_buffer.length() * 2); |
| 375 own_buffer_ = true; |
| 376 memcpy(buffer_.start(), old_buffer.start(), old_buffer.length()); |
| 377 if (old_buffer_was_our_own) { |
| 378 old_buffer.Dispose(); |
| 379 } |
| 380 } |
| 381 |
| 382 |
280 } } // namespace v8::internal | 383 } } // namespace v8::internal |
OLD | NEW |