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

Side by Side Diff: src/js/regexp.js

Issue 1448933002: Introduce a BuiltinsConstructStub that sets up new.target and does a [[call]] per ES6 9.3.2 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: More accurate regexp Created 5 years, 1 month 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 (function(global, utils) { 5 (function(global, utils) {
6 6
7 %CheckIsBootstrapping(); 7 %CheckIsBootstrapping();
8 8
9 // ------------------------------------------------------------------- 9 // -------------------------------------------------------------------
10 // Imports 10 // Imports
11 11
12 var FLAG_harmony_tolength; 12 var FLAG_harmony_tolength;
13 var GlobalObject = global.Object; 13 var GlobalObject = global.Object;
14 var GlobalRegExp = global.RegExp; 14 var GlobalRegExp = global.RegExp;
15 var InternalArray = utils.InternalArray; 15 var InternalArray = utils.InternalArray;
16 var InternalPackedArray = utils.InternalPackedArray; 16 var InternalPackedArray = utils.InternalPackedArray;
17 var MakeTypeError; 17 var MakeTypeError;
18 var splitSymbol = utils.ImportNow("split_symbol"); 18 var splitSymbol = utils.ImportNow("split_symbol");
19 var matchSymbol = utils.ImportNow("match_symbol");;
19 20
20 utils.ImportFromExperimental(function(from) { 21 utils.ImportFromExperimental(function(from) {
21 FLAG_harmony_tolength = from.FLAG_harmony_tolength; 22 FLAG_harmony_tolength = from.FLAG_harmony_tolength;
22 }); 23 });
23 24
24 utils.Import(function(from) { 25 utils.Import(function(from) {
25 MakeTypeError = from.MakeTypeError; 26 MakeTypeError = from.MakeTypeError;
26 }); 27 });
27 28
28 // ------------------------------------------------------------------- 29 // -------------------------------------------------------------------
29 30
30 // Property of the builtins object for recording the result of the last 31 // Property of the builtins object for recording the result of the last
31 // regexp match. The property RegExpLastMatchInfo includes the matchIndices 32 // regexp match. The property RegExpLastMatchInfo includes the matchIndices
32 // array of the last successful regexp match (an array of start/end index 33 // array of the last successful regexp match (an array of start/end index
33 // pairs for the match and all the captured substrings), the invariant is 34 // pairs for the match and all the captured substrings), the invariant is
34 // that there are at least two capture indeces. The array also contains 35 // that there are at least two capture indeces. The array also contains
35 // the subject string for the last successful match. 36 // the subject string for the last successful match.
36 var RegExpLastMatchInfo = new InternalPackedArray( 37 var RegExpLastMatchInfo = new InternalPackedArray(
37 2, // REGEXP_NUMBER_OF_CAPTURES 38 2, // REGEXP_NUMBER_OF_CAPTURES
38 "", // Last subject. 39 "", // Last subject.
39 UNDEFINED, // Last input - settable with RegExpSetInput. 40 UNDEFINED, // Last input - settable with RegExpSetInput.
40 0, // REGEXP_FIRST_CAPTURE + 0 41 0, // REGEXP_FIRST_CAPTURE + 0
41 0 // REGEXP_FIRST_CAPTURE + 1 42 0 // REGEXP_FIRST_CAPTURE + 1
42 ); 43 );
43 44
44 // ------------------------------------------------------------------- 45 // -------------------------------------------------------------------
45 46
46 // A recursive descent parser for Patterns according to the grammar of 47 function IsRegExp(o) {
47 // ECMA-262 15.10.1, with deviations noted below. 48 if (!IS_OBJECT(o)) return false;
48 function DoConstructRegExp(object, pattern, flags) { 49 var is_regexp = o[matchSymbol];
49 // RegExp : Called as constructor; see ECMA-262, section 15.10.4. 50 if (!IS_UNDEFINED(is_regexp)) return TO_BOOLEAN(is_regexp);
51 return IS_REGEXP(o);
52 }
53
54
55 // ES6 section 21.2.3.2.2
56 function RegExpInitialize(object, pattern, flags) {
57 pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern);
58 flags = IS_UNDEFINED(flags) ? '' : TO_STRING(flags);
59 %RegExpInitializeAndCompile(object, pattern, flags);
60 return object;
61 }
62
63
64 function RegExpConstructor(pattern, flags) {
65 var newtarget = new.target;
66 var pattern_is_regexp = IsRegExp(pattern);
67
68 if (IS_UNDEFINED(newtarget)) {
69 newtarget = GlobalRegExp;
70
71 // ES6 section 21.2.3.1 step 3.b
72 if (pattern_is_regexp && IS_UNDEFINED(flags) &&
73 pattern.constructor === newtarget) {
74 return pattern;
75 }
76 }
77
78 if (IS_REGEXP(pattern)) {
79 if (IS_UNDEFINED(flags)) {
80 flags = (REGEXP_GLOBAL(pattern) ? 'g' : '')
Igor Sheludko 2015/11/19 09:30:53 We do this kind of thing in three places already,
81 + (REGEXP_IGNORE_CASE(pattern) ? 'i' : '')
82 + (REGEXP_MULTILINE(pattern) ? 'm' : '')
83 + (REGEXP_UNICODE(pattern) ? 'u' : '')
84 + (REGEXP_STICKY(pattern) ? 'y' : '');
85 }
86 pattern = REGEXP_SOURCE(pattern);
87
88 } else if (pattern_is_regexp) {
89 var input_pattern = pattern;
90 pattern = pattern.source;
Igor Sheludko 2015/11/19 09:30:53 Shouldn't this be a REGEXP_SOURCE(pattern) instead
Toon Verwaest 2015/11/19 09:39:53 We actually have to do Get(..."source") and "flags
91 if (IS_UNDEFINED(flags)) flags = input_pattern.flags;
92 }
93
94 var object = %NewObject(GlobalRegExp, newtarget);
95 return RegExpInitialize(object, pattern, flags);
96 }
97
98
99 function RegExpCompileJS(pattern, flags) {
100 if (!IS_REGEXP(this)) {
101 throw MakeTypeError(kIncompatibleMethodReceiver,
102 "RegExp.prototype.compile", this);
103 }
104
50 if (IS_REGEXP(pattern)) { 105 if (IS_REGEXP(pattern)) {
51 if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags); 106 if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags);
107
52 flags = (REGEXP_GLOBAL(pattern) ? 'g' : '') 108 flags = (REGEXP_GLOBAL(pattern) ? 'g' : '')
53 + (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') 109 + (REGEXP_IGNORE_CASE(pattern) ? 'i' : '')
54 + (REGEXP_MULTILINE(pattern) ? 'm' : '') 110 + (REGEXP_MULTILINE(pattern) ? 'm' : '')
55 + (REGEXP_UNICODE(pattern) ? 'u' : '') 111 + (REGEXP_UNICODE(pattern) ? 'u' : '')
56 + (REGEXP_STICKY(pattern) ? 'y' : ''); 112 + (REGEXP_STICKY(pattern) ? 'y' : '');
57 pattern = REGEXP_SOURCE(pattern); 113 pattern = REGEXP_SOURCE(pattern);
58 } 114 }
59 115
60 pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern); 116 return RegExpInitialize(this, pattern, flags);
61 flags = IS_UNDEFINED(flags) ? '' : TO_STRING(flags);
62
63 %RegExpInitializeAndCompile(object, pattern, flags);
64 } 117 }
65 118
66 119
67 function RegExpConstructor(pattern, flags) {
68 if (%_IsConstructCall()) {
69 DoConstructRegExp(this, pattern, flags);
70 } else {
71 // RegExp : Called as function; see ECMA-262, section 15.10.3.1.
72 if (IS_REGEXP(pattern) && IS_UNDEFINED(flags)) {
73 return pattern;
74 }
75 return new GlobalRegExp(pattern, flags);
76 }
77 }
78
79 // Deprecated RegExp.prototype.compile method. We behave like the constructor
80 // were called again. In SpiderMonkey, this method returns the regexp object.
81 // In JSC, it returns undefined. For compatibility with JSC, we match their
82 // behavior.
83 function RegExpCompileJS(pattern, flags) {
84 // Both JSC and SpiderMonkey treat a missing pattern argument as the
85 // empty subject string, and an actual undefined value passed as the
86 // pattern as the string 'undefined'. Note that JSC is inconsistent
87 // here, treating undefined values differently in
88 // RegExp.prototype.compile and in the constructor, where they are
89 // the empty string. For compatibility with JSC, we match their
90 // behavior.
91 if (this == GlobalRegExp.prototype) {
92 // We don't allow recompiling RegExp.prototype.
93 throw MakeTypeError(kIncompatibleMethodReceiver,
94 'RegExp.prototype.compile', this);
95 }
96 if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) {
97 DoConstructRegExp(this, 'undefined', flags);
98 } else {
99 DoConstructRegExp(this, pattern, flags);
100 }
101 }
102
103
104 function DoRegExpExec(regexp, string, index) { 120 function DoRegExpExec(regexp, string, index) {
105 var result = %_RegExpExec(regexp, string, index, RegExpLastMatchInfo); 121 var result = %_RegExpExec(regexp, string, index, RegExpLastMatchInfo);
106 return result; 122 return result;
107 } 123 }
108 124
109 125
110 // This is kind of performance sensitive, so we want to avoid unnecessary 126 // This is kind of performance sensitive, so we want to avoid unnecessary
111 // type checks on inputs. But we also don't want to inline it several times 127 // type checks on inputs. But we also don't want to inline it several times
112 // manually, so we use a macro :-) 128 // manually, so we use a macro :-)
113 macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING) 129 macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING)
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 // Exports 533 // Exports
518 534
519 utils.Export(function(to) { 535 utils.Export(function(to) {
520 to.RegExpExec = DoRegExpExec; 536 to.RegExpExec = DoRegExpExec;
521 to.RegExpExecNoTests = RegExpExecNoTests; 537 to.RegExpExecNoTests = RegExpExecNoTests;
522 to.RegExpLastMatchInfo = RegExpLastMatchInfo; 538 to.RegExpLastMatchInfo = RegExpLastMatchInfo;
523 to.RegExpTest = RegExpTest; 539 to.RegExpTest = RegExpTest;
524 }); 540 });
525 541
526 }) 542 })
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698