OLD | NEW |
---|---|
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 'use strict'; | 7 'use strict'; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 if (!IS_RECEIVER(this)) { | 337 if (!IS_RECEIVER(this)) { |
338 throw %make_type_error(kIncompatibleMethodReceiver, | 338 throw %make_type_error(kIncompatibleMethodReceiver, |
339 "RegExp.prototype.@@split", this); | 339 "RegExp.prototype.@@split", this); |
340 } | 340 } |
341 string = TO_STRING(string); | 341 string = TO_STRING(string); |
342 var constructor = SpeciesConstructor(this, GlobalRegExp); | 342 var constructor = SpeciesConstructor(this, GlobalRegExp); |
343 var flags = TO_STRING(this.flags); | 343 var flags = TO_STRING(this.flags); |
344 | 344 |
345 // TODO(adamk): this fast path is wrong as we doesn't ensure that 'exec' | 345 // TODO(adamk): this fast path is wrong as we doesn't ensure that 'exec' |
346 // is actually a data property on RegExp.prototype. | 346 // is actually a data property on RegExp.prototype. |
347 var exec; | |
348 if (IS_REGEXP(this) && constructor === GlobalRegExp) { | 347 if (IS_REGEXP(this) && constructor === GlobalRegExp) { |
349 exec = this.exec; | 348 var exec = this.exec; |
Dan Ehrenberg
2016/09/26 14:16:27
Doesn't this initial, additional read of exec viol
jgruber
2016/09/26 14:19:37
I'm not sure which additional read you mean? This
| |
350 if (exec === RegExpExecJS) { | 349 if (exec === RegExpExecJS) { |
351 return %_Call(RegExpSplit, this, string, limit); | 350 return %_Call(RegExpSplit, this, string, limit); |
352 } | 351 } |
353 } | 352 } |
354 | 353 |
355 var unicode = %StringIndexOf(flags, 'u', 0) >= 0; | 354 var unicode = %StringIndexOf(flags, 'u', 0) >= 0; |
356 var sticky = %StringIndexOf(flags, 'y', 0) >= 0; | 355 var sticky = %StringIndexOf(flags, 'y', 0) >= 0; |
357 var newFlags = sticky ? flags : flags + "y"; | 356 var newFlags = sticky ? flags : flags + "y"; |
358 var splitter = new constructor(this, newFlags); | 357 var splitter = new constructor(this, newFlags); |
359 var array = new GlobalArray(); | 358 var array = new GlobalArray(); |
360 var arrayIndex = 0; | 359 var arrayIndex = 0; |
361 var lim = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); | 360 var lim = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); |
362 var size = string.length; | 361 var size = string.length; |
363 var prevStringIndex = 0; | 362 var prevStringIndex = 0; |
364 if (lim === 0) return array; | 363 if (lim === 0) return array; |
365 var result; | 364 var result; |
366 if (size === 0) { | 365 if (size === 0) { |
367 result = RegExpSubclassExec(splitter, string); | 366 result = RegExpSubclassExec(splitter, string); |
368 if (IS_NULL(result)) %AddElement(array, 0, string); | 367 if (IS_NULL(result)) %AddElement(array, 0, string); |
369 return array; | 368 return array; |
370 } | 369 } |
371 var stringIndex = prevStringIndex; | 370 var stringIndex = prevStringIndex; |
372 while (stringIndex < size) { | 371 while (stringIndex < size) { |
373 splitter.lastIndex = stringIndex; | 372 splitter.lastIndex = stringIndex; |
374 result = RegExpSubclassExec(splitter, string, exec); | 373 result = RegExpSubclassExec(splitter, string); |
Dan Ehrenberg
2016/09/26 14:30:33
By not passing exec here, an additional read of ex
jgruber
2016/09/26 14:57:23
I see.
But do we care about the additional exec r
| |
375 // Ensure exec will be read again on the next loop through. | |
376 exec = UNDEFINED; | |
377 if (IS_NULL(result)) { | 374 if (IS_NULL(result)) { |
378 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); | 375 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); |
379 } else { | 376 } else { |
380 var end = MinSimple(TO_LENGTH(splitter.lastIndex), size); | 377 var end = MinSimple(TO_LENGTH(splitter.lastIndex), size); |
381 if (end === prevStringIndex) { | 378 if (end === prevStringIndex) { |
382 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); | 379 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); |
383 } else { | 380 } else { |
384 %AddElement( | 381 %AddElement( |
385 array, arrayIndex, | 382 array, arrayIndex, |
386 %_SubString(string, prevStringIndex, stringIndex)); | 383 %_SubString(string, prevStringIndex, stringIndex)); |
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1128 to.GetSubstitution = GetSubstitution; | 1125 to.GetSubstitution = GetSubstitution; |
1129 to.InternalRegExpMatch = InternalRegExpMatch; | 1126 to.InternalRegExpMatch = InternalRegExpMatch; |
1130 to.InternalRegExpReplace = InternalRegExpReplace; | 1127 to.InternalRegExpReplace = InternalRegExpReplace; |
1131 to.IsRegExp = IsRegExp; | 1128 to.IsRegExp = IsRegExp; |
1132 to.RegExpExec = DoRegExpExec; | 1129 to.RegExpExec = DoRegExpExec; |
1133 to.RegExpInitialize = RegExpInitialize; | 1130 to.RegExpInitialize = RegExpInitialize; |
1134 to.RegExpLastMatchInfo = RegExpLastMatchInfo; | 1131 to.RegExpLastMatchInfo = RegExpLastMatchInfo; |
1135 }); | 1132 }); |
1136 | 1133 |
1137 }) | 1134 }) |
OLD | NEW |