Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: src/builtins/builtins-regexp-gen.cc

Issue 2863643004: [regexp] Avoid runtime call on OOB lastIndex values (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-regexp-gen.h" 5 #include "src/builtins/builtins-regexp-gen.h"
6 6
7 #include "src/builtins/builtins-constructor-gen.h" 7 #include "src/builtins/builtins-constructor-gen.h"
8 #include "src/builtins/builtins-utils-gen.h" 8 #include "src/builtins/builtins-utils-gen.h"
9 #include "src/builtins/builtins.h" 9 #include "src/builtins/builtins.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 #ifdef V8_INTERPRETED_REGEXP 242 #ifdef V8_INTERPRETED_REGEXP
243 return CallRuntime(Runtime::kRegExpExec, context, regexp, string, last_index, 243 return CallRuntime(Runtime::kRegExpExec, context, regexp, string, last_index,
244 match_info); 244 match_info);
245 #else // V8_INTERPRETED_REGEXP 245 #else // V8_INTERPRETED_REGEXP
246 CSA_ASSERT(this, TaggedIsNotSmi(regexp)); 246 CSA_ASSERT(this, TaggedIsNotSmi(regexp));
247 CSA_ASSERT(this, IsJSRegExp(regexp)); 247 CSA_ASSERT(this, IsJSRegExp(regexp));
248 248
249 CSA_ASSERT(this, TaggedIsNotSmi(string)); 249 CSA_ASSERT(this, TaggedIsNotSmi(string));
250 CSA_ASSERT(this, IsString(string)); 250 CSA_ASSERT(this, IsString(string));
251 251
252 CSA_ASSERT(this, IsNumber(last_index)); 252 CSA_ASSERT(this, IsNumber(last_index));
Jakob Kummerow 2017/05/05 15:35:55 nit: you can move the IsNumberNormalized check her
jgruber 2017/05/05 15:53:33 I wanted to keep the assert close to relevant code
253 CSA_ASSERT(this, IsFixedArrayMap(LoadReceiverMap(match_info))); 253 CSA_ASSERT(this, IsFixedArrayMap(LoadReceiverMap(match_info)));
254 254
255 Node* const int_zero = IntPtrConstant(0); 255 Node* const int_zero = IntPtrConstant(0);
256 256
257 ToDirectStringAssembler to_direct(state(), string); 257 ToDirectStringAssembler to_direct(state(), string);
258 258
259 VARIABLE(var_result, MachineRepresentation::kTagged); 259 VARIABLE(var_result, MachineRepresentation::kTagged);
260 Label out(this), runtime(this, Label::kDeferred); 260 Label out(this), runtime(this, Label::kDeferred);
261 261
262 // External constants. 262 // External constants.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 SmiConstant(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1)), 299 SmiConstant(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1)),
300 &runtime); 300 &runtime);
301 } 301 }
302 302
303 // Unpack the string if possible. 303 // Unpack the string if possible.
304 304
305 to_direct.TryToDirect(&runtime); 305 to_direct.TryToDirect(&runtime);
306 306
307 Node* const smi_string_length = LoadStringLength(string); 307 Node* const smi_string_length = LoadStringLength(string);
308 308
309 // Bail out to runtime for invalid {last_index} values. 309 // At this point, last_index is definitely a canonicalized non-negative
310 GotoIfNot(TaggedIsSmi(last_index), &runtime); 310 // number, which implies that any non-Smi last_index is greater than
311 GotoIf(SmiAboveOrEqual(last_index, smi_string_length), &runtime); 311 // the maximal string length. If lastIndex > string.length then the matcher
312 // must fail.
313
314 Label if_failure(this);
315 CSA_ASSERT(this, IsNumberNormalized(last_index));
316 GotoIfNot(TaggedIsSmi(last_index), &if_failure); // Outside Smi range.
317 GotoIf(SmiAbove(last_index, smi_string_length), &if_failure);
312 318
313 // Load the irregexp code object and offsets into the subject string. Both 319 // Load the irregexp code object and offsets into the subject string. Both
314 // depend on whether the string is one- or two-byte. 320 // depend on whether the string is one- or two-byte.
315 321
316 Node* const int_last_index = SmiUntag(last_index); 322 Node* const int_last_index = SmiUntag(last_index);
317 323
318 VARIABLE(var_string_start, MachineType::PointerRepresentation()); 324 VARIABLE(var_string_start, MachineType::PointerRepresentation());
319 VARIABLE(var_string_end, MachineType::PointerRepresentation()); 325 VARIABLE(var_string_end, MachineType::PointerRepresentation());
320 VARIABLE(var_code, MachineRepresentation::kTagged); 326 VARIABLE(var_code, MachineRepresentation::kTagged);
321 327
(...skipping 29 matching lines...) Expand all
351 } 357 }
352 358
353 // Check that the irregexp code has been generated for the actual string 359 // Check that the irregexp code has been generated for the actual string
354 // encoding. If it has, the field contains a code object otherwise it contains 360 // encoding. If it has, the field contains a code object otherwise it contains
355 // smi (code flushing support). 361 // smi (code flushing support).
356 362
357 Node* const code = var_code.value(); 363 Node* const code = var_code.value();
358 GotoIf(TaggedIsSmi(code), &runtime); 364 GotoIf(TaggedIsSmi(code), &runtime);
359 CSA_ASSERT(this, HasInstanceType(code, CODE_TYPE)); 365 CSA_ASSERT(this, HasInstanceType(code, CODE_TYPE));
360 366
361 Label if_success(this), if_failure(this), 367 Label if_success(this), if_exception(this, Label::kDeferred);
362 if_exception(this, Label::kDeferred);
363 { 368 {
364 IncrementCounter(isolate()->counters()->regexp_entry_native(), 1); 369 IncrementCounter(isolate()->counters()->regexp_entry_native(), 1);
365 370
366 // Set up args for the final call into generated Irregexp code. 371 // Set up args for the final call into generated Irregexp code.
367 372
368 MachineType type_int32 = MachineType::Int32(); 373 MachineType type_int32 = MachineType::Int32();
369 MachineType type_tagged = MachineType::AnyTagged(); 374 MachineType type_tagged = MachineType::AnyTagged();
370 MachineType type_ptr = MachineType::Pointer(); 375 MachineType type_ptr = MachineType::Pointer();
371 376
372 // Result: A NativeRegExpMacroAssembler::Result return code. 377 // Result: A NativeRegExpMacroAssembler::Result return code.
(...skipping 2545 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 BIND(&if_matched); 2923 BIND(&if_matched);
2919 { 2924 {
2920 Node* result = 2925 Node* result =
2921 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2926 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2922 Return(result); 2927 Return(result);
2923 } 2928 }
2924 } 2929 }
2925 2930
2926 } // namespace internal 2931 } // namespace internal
2927 } // namespace v8 2932 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698