| 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 %CheckIsBootstrapping(); | 7 %CheckIsBootstrapping(); |
| 8 | 8 |
| 9 // ------------------------------------------------------------------- | 9 // ------------------------------------------------------------------- |
| 10 // Imports | 10 // Imports |
| 11 | 11 |
| 12 var ExpandReplacement; | 12 var ExpandReplacement; |
| 13 var GlobalArray = global.Array; | 13 var GlobalArray = global.Array; |
| 14 var GlobalObject = global.Object; | 14 var GlobalObject = global.Object; |
| 15 var GlobalRegExp = global.RegExp; | 15 var GlobalRegExp = global.RegExp; |
| 16 var GlobalRegExpPrototype; | 16 var GlobalRegExpPrototype; |
| 17 var InternalArray = utils.InternalArray; | 17 var InternalArray = utils.InternalArray; |
| 18 var InternalPackedArray = utils.InternalPackedArray; | 18 var InternalPackedArray = utils.InternalPackedArray; |
| 19 var MakeTypeError; | |
| 20 var MaxSimple; | 19 var MaxSimple; |
| 21 var MinSimple; | 20 var MinSimple; |
| 22 var matchSymbol = utils.ImportNow("match_symbol"); | 21 var matchSymbol = utils.ImportNow("match_symbol"); |
| 23 var replaceSymbol = utils.ImportNow("replace_symbol"); | 22 var replaceSymbol = utils.ImportNow("replace_symbol"); |
| 24 var searchSymbol = utils.ImportNow("search_symbol"); | 23 var searchSymbol = utils.ImportNow("search_symbol"); |
| 25 var speciesSymbol = utils.ImportNow("species_symbol"); | 24 var speciesSymbol = utils.ImportNow("species_symbol"); |
| 26 var splitSymbol = utils.ImportNow("split_symbol"); | 25 var splitSymbol = utils.ImportNow("split_symbol"); |
| 27 var SpeciesConstructor; | 26 var SpeciesConstructor; |
| 28 | 27 |
| 29 utils.Import(function(from) { | 28 utils.Import(function(from) { |
| 30 ExpandReplacement = from.ExpandReplacement; | 29 ExpandReplacement = from.ExpandReplacement; |
| 31 MakeTypeError = from.MakeTypeError; | |
| 32 MaxSimple = from.MaxSimple; | 30 MaxSimple = from.MaxSimple; |
| 33 MinSimple = from.MinSimple; | 31 MinSimple = from.MinSimple; |
| 34 SpeciesConstructor = from.SpeciesConstructor; | 32 SpeciesConstructor = from.SpeciesConstructor; |
| 35 }); | 33 }); |
| 36 | 34 |
| 37 // ------------------------------------------------------------------- | 35 // ------------------------------------------------------------------- |
| 38 | 36 |
| 39 // Property of the builtins object for recording the result of the last | 37 // Property of the builtins object for recording the result of the last |
| 40 // regexp match. The property RegExpLastMatchInfo includes the matchIndices | 38 // regexp match. The property RegExpLastMatchInfo includes the matchIndices |
| 41 // array of the last successful regexp match (an array of start/end index | 39 // array of the last successful regexp match (an array of start/end index |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 } | 105 } |
| 108 | 106 |
| 109 var object = %_NewObject(GlobalRegExp, newtarget); | 107 var object = %_NewObject(GlobalRegExp, newtarget); |
| 110 return RegExpInitialize(object, pattern, flags); | 108 return RegExpInitialize(object, pattern, flags); |
| 111 } | 109 } |
| 112 | 110 |
| 113 | 111 |
| 114 // ES#sec-regexp.prototype.compile RegExp.prototype.compile (pattern, flags) | 112 // ES#sec-regexp.prototype.compile RegExp.prototype.compile (pattern, flags) |
| 115 function RegExpCompileJS(pattern, flags) { | 113 function RegExpCompileJS(pattern, flags) { |
| 116 if (!IS_REGEXP(this)) { | 114 if (!IS_REGEXP(this)) { |
| 117 throw MakeTypeError(kIncompatibleMethodReceiver, | 115 throw %make_type_error(kIncompatibleMethodReceiver, |
| 118 "RegExp.prototype.compile", this); | 116 "RegExp.prototype.compile", this); |
| 119 } | 117 } |
| 120 | 118 |
| 121 if (IS_REGEXP(pattern)) { | 119 if (IS_REGEXP(pattern)) { |
| 122 if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags); | 120 if (!IS_UNDEFINED(flags)) throw %make_type_error(kRegExpFlags); |
| 123 | 121 |
| 124 flags = PatternFlags(pattern); | 122 flags = PatternFlags(pattern); |
| 125 pattern = REGEXP_SOURCE(pattern); | 123 pattern = REGEXP_SOURCE(pattern); |
| 126 } | 124 } |
| 127 | 125 |
| 128 RegExpInitialize(this, pattern, flags); | 126 RegExpInitialize(this, pattern, flags); |
| 129 | 127 |
| 130 // Return undefined for compatibility with JSC. | 128 // Return undefined for compatibility with JSC. |
| 131 // See http://crbug.com/585775 for web compat details. | 129 // See http://crbug.com/585775 for web compat details. |
| 132 } | 130 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 } | 171 } |
| 174 regexp.lastIndex = 0; | 172 regexp.lastIndex = 0; |
| 175 return null; | 173 return null; |
| 176 } | 174 } |
| 177 | 175 |
| 178 | 176 |
| 179 // ES#sec-regexp.prototype.exec | 177 // ES#sec-regexp.prototype.exec |
| 180 // RegExp.prototype.exec ( string ) | 178 // RegExp.prototype.exec ( string ) |
| 181 function RegExpSubclassExecJS(string) { | 179 function RegExpSubclassExecJS(string) { |
| 182 if (!IS_REGEXP(this)) { | 180 if (!IS_REGEXP(this)) { |
| 183 throw MakeTypeError(kIncompatibleMethodReceiver, | 181 throw %make_type_error(kIncompatibleMethodReceiver, |
| 184 'RegExp.prototype.exec', this); | 182 'RegExp.prototype.exec', this); |
| 185 } | 183 } |
| 186 | 184 |
| 187 string = TO_STRING(string); | 185 string = TO_STRING(string); |
| 188 var lastIndex = this.lastIndex; | 186 var lastIndex = this.lastIndex; |
| 189 | 187 |
| 190 // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 188 // Conversion is required by the ES2015 specification (RegExpBuiltinExec |
| 191 // algorithm, step 4) even if the value is discarded for non-global RegExps. | 189 // algorithm, step 4) even if the value is discarded for non-global RegExps. |
| 192 var i = TO_LENGTH(lastIndex); | 190 var i = TO_LENGTH(lastIndex); |
| 193 | 191 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 219 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 217 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; |
| 220 } | 218 } |
| 221 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); | 219 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); |
| 222 } | 220 } |
| 223 %FunctionRemovePrototype(RegExpSubclassExecJS); | 221 %FunctionRemovePrototype(RegExpSubclassExecJS); |
| 224 | 222 |
| 225 | 223 |
| 226 // Legacy implementation of RegExp.prototype.exec | 224 // Legacy implementation of RegExp.prototype.exec |
| 227 function RegExpExecJS(string) { | 225 function RegExpExecJS(string) { |
| 228 if (!IS_REGEXP(this)) { | 226 if (!IS_REGEXP(this)) { |
| 229 throw MakeTypeError(kIncompatibleMethodReceiver, | 227 throw %make_type_error(kIncompatibleMethodReceiver, |
| 230 'RegExp.prototype.exec', this); | 228 'RegExp.prototype.exec', this); |
| 231 } | 229 } |
| 232 | 230 |
| 233 string = TO_STRING(string); | 231 string = TO_STRING(string); |
| 234 var lastIndex = this.lastIndex; | 232 var lastIndex = this.lastIndex; |
| 235 | 233 |
| 236 // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 234 // Conversion is required by the ES2015 specification (RegExpBuiltinExec |
| 237 // algorithm, step 4) even if the value is discarded for non-global RegExps. | 235 // algorithm, step 4) even if the value is discarded for non-global RegExps. |
| 238 var i = TO_LENGTH(lastIndex); | 236 var i = TO_LENGTH(lastIndex); |
| 239 | 237 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 266 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) | 264 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) |
| 267 // Also takes an optional exec method in case our caller | 265 // Also takes an optional exec method in case our caller |
| 268 // has already fetched exec. | 266 // has already fetched exec. |
| 269 function RegExpSubclassExec(regexp, string, exec) { | 267 function RegExpSubclassExec(regexp, string, exec) { |
| 270 if (IS_UNDEFINED(exec)) { | 268 if (IS_UNDEFINED(exec)) { |
| 271 exec = regexp.exec; | 269 exec = regexp.exec; |
| 272 } | 270 } |
| 273 if (IS_CALLABLE(exec)) { | 271 if (IS_CALLABLE(exec)) { |
| 274 var result = %_Call(exec, regexp, string); | 272 var result = %_Call(exec, regexp, string); |
| 275 if (!IS_RECEIVER(result) && !IS_NULL(result)) { | 273 if (!IS_RECEIVER(result) && !IS_NULL(result)) { |
| 276 throw MakeTypeError(kInvalidRegExpExecResult); | 274 throw %make_type_error(kInvalidRegExpExecResult); |
| 277 } | 275 } |
| 278 return result; | 276 return result; |
| 279 } | 277 } |
| 280 return %_Call(RegExpExecJS, regexp, string); | 278 return %_Call(RegExpExecJS, regexp, string); |
| 281 } | 279 } |
| 282 %SetForceInlineFlag(RegExpSubclassExec); | 280 %SetForceInlineFlag(RegExpSubclassExec); |
| 283 | 281 |
| 284 | 282 |
| 285 // One-element cache for the simplified test regexp. | 283 // One-element cache for the simplified test regexp. |
| 286 var regexp_key; | 284 var regexp_key; |
| 287 var regexp_val; | 285 var regexp_val; |
| 288 | 286 |
| 289 // Legacy implementation of RegExp.prototype.test | 287 // Legacy implementation of RegExp.prototype.test |
| 290 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be | 288 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be |
| 291 // that test is defined in terms of String.prototype.exec. However, it probably | 289 // that test is defined in terms of String.prototype.exec. However, it probably |
| 292 // means the original value of String.prototype.exec, which is what everybody | 290 // means the original value of String.prototype.exec, which is what everybody |
| 293 // else implements. | 291 // else implements. |
| 294 function RegExpTest(string) { | 292 function RegExpTest(string) { |
| 295 if (!IS_REGEXP(this)) { | 293 if (!IS_REGEXP(this)) { |
| 296 throw MakeTypeError(kIncompatibleMethodReceiver, | 294 throw %make_type_error(kIncompatibleMethodReceiver, |
| 297 'RegExp.prototype.test', this); | 295 'RegExp.prototype.test', this); |
| 298 } | 296 } |
| 299 string = TO_STRING(string); | 297 string = TO_STRING(string); |
| 300 | 298 |
| 301 var lastIndex = this.lastIndex; | 299 var lastIndex = this.lastIndex; |
| 302 | 300 |
| 303 // Conversion is required by the ES2015 specification (RegExpBuiltinExec | 301 // Conversion is required by the ES2015 specification (RegExpBuiltinExec |
| 304 // algorithm, step 4) even if the value is discarded for non-global RegExps. | 302 // algorithm, step 4) even if the value is discarded for non-global RegExps. |
| 305 var i = TO_LENGTH(lastIndex); | 303 var i = TO_LENGTH(lastIndex); |
| 306 | 304 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 337 return false; | 335 return false; |
| 338 } | 336 } |
| 339 return true; | 337 return true; |
| 340 } | 338 } |
| 341 } | 339 } |
| 342 | 340 |
| 343 | 341 |
| 344 // ES#sec-regexp.prototype.test RegExp.prototype.test ( S ) | 342 // ES#sec-regexp.prototype.test RegExp.prototype.test ( S ) |
| 345 function RegExpSubclassTest(string) { | 343 function RegExpSubclassTest(string) { |
| 346 if (!IS_RECEIVER(this)) { | 344 if (!IS_RECEIVER(this)) { |
| 347 throw MakeTypeError(kIncompatibleMethodReceiver, | 345 throw %make_type_error(kIncompatibleMethodReceiver, |
| 348 'RegExp.prototype.test', this); | 346 'RegExp.prototype.test', this); |
| 349 } | 347 } |
| 350 string = TO_STRING(string); | 348 string = TO_STRING(string); |
| 351 var match = RegExpSubclassExec(this, string); | 349 var match = RegExpSubclassExec(this, string); |
| 352 return !IS_NULL(match); | 350 return !IS_NULL(match); |
| 353 } | 351 } |
| 354 %FunctionRemovePrototype(RegExpSubclassTest); | 352 %FunctionRemovePrototype(RegExpSubclassTest); |
| 355 | 353 |
| 356 function TrimRegExp(regexp) { | 354 function TrimRegExp(regexp) { |
| 357 if (regexp_key !== regexp) { | 355 if (regexp_key !== regexp) { |
| 358 regexp_key = regexp; | 356 regexp_key = regexp; |
| 359 regexp_val = | 357 regexp_val = |
| 360 new GlobalRegExp( | 358 new GlobalRegExp( |
| 361 %_SubString(REGEXP_SOURCE(regexp), 2, REGEXP_SOURCE(regexp).length), | 359 %_SubString(REGEXP_SOURCE(regexp), 2, REGEXP_SOURCE(regexp).length), |
| 362 (REGEXP_IGNORE_CASE(regexp) ? REGEXP_MULTILINE(regexp) ? "im" : "i" | 360 (REGEXP_IGNORE_CASE(regexp) ? REGEXP_MULTILINE(regexp) ? "im" : "i" |
| 363 : REGEXP_MULTILINE(regexp) ? "m" : "")); | 361 : REGEXP_MULTILINE(regexp) ? "m" : "")); |
| 364 } | 362 } |
| 365 return regexp_val; | 363 return regexp_val; |
| 366 } | 364 } |
| 367 | 365 |
| 368 | 366 |
| 369 function RegExpToString() { | 367 function RegExpToString() { |
| 370 if (!IS_RECEIVER(this)) { | 368 if (!IS_RECEIVER(this)) { |
| 371 throw MakeTypeError( | 369 throw %make_type_error( |
| 372 kIncompatibleMethodReceiver, 'RegExp.prototype.toString', this); | 370 kIncompatibleMethodReceiver, 'RegExp.prototype.toString', this); |
| 373 } | 371 } |
| 374 if (this === GlobalRegExpPrototype) { | 372 if (this === GlobalRegExpPrototype) { |
| 375 %IncrementUseCounter(kRegExpPrototypeToString); | 373 %IncrementUseCounter(kRegExpPrototypeToString); |
| 376 } | 374 } |
| 377 return '/' + TO_STRING(this.source) + '/' + TO_STRING(this.flags); | 375 return '/' + TO_STRING(this.source) + '/' + TO_STRING(this.flags); |
| 378 } | 376 } |
| 379 | 377 |
| 380 | 378 |
| 381 function AtSurrogatePair(subject, index) { | 379 function AtSurrogatePair(subject, index) { |
| 382 if (index + 1 >= subject.length) return false; | 380 if (index + 1 >= subject.length) return false; |
| 383 var first = %_StringCharCodeAt(subject, index); | 381 var first = %_StringCharCodeAt(subject, index); |
| 384 if (first < 0xD800 || first > 0xDBFF) return false; | 382 if (first < 0xD800 || first > 0xDBFF) return false; |
| 385 var second = %_StringCharCodeAt(subject, index + 1); | 383 var second = %_StringCharCodeAt(subject, index + 1); |
| 386 return second >= 0xDC00 || second <= 0xDFFF; | 384 return second >= 0xDC00 || second <= 0xDFFF; |
| 387 } | 385 } |
| 388 | 386 |
| 389 | 387 |
| 390 // Legacy implementation of RegExp.prototype[Symbol.split] which | 388 // Legacy implementation of RegExp.prototype[Symbol.split] which |
| 391 // doesn't properly call the underlying exec, @@species methods | 389 // doesn't properly call the underlying exec, @@species methods |
| 392 function RegExpSplit(string, limit) { | 390 function RegExpSplit(string, limit) { |
| 393 // TODO(yangguo): allow non-regexp receivers. | 391 // TODO(yangguo): allow non-regexp receivers. |
| 394 if (!IS_REGEXP(this)) { | 392 if (!IS_REGEXP(this)) { |
| 395 throw MakeTypeError(kIncompatibleMethodReceiver, | 393 throw %make_type_error(kIncompatibleMethodReceiver, |
| 396 "RegExp.prototype.@@split", this); | 394 "RegExp.prototype.@@split", this); |
| 397 } | 395 } |
| 398 var separator = this; | 396 var separator = this; |
| 399 var subject = TO_STRING(string); | 397 var subject = TO_STRING(string); |
| 400 | 398 |
| 401 limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); | 399 limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); |
| 402 var length = subject.length; | 400 var length = subject.length; |
| 403 | 401 |
| 404 if (limit === 0) return []; | 402 if (limit === 0) return []; |
| 405 | 403 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 var array_result = []; | 457 var array_result = []; |
| 460 %MoveArrayContents(result, array_result); | 458 %MoveArrayContents(result, array_result); |
| 461 return array_result; | 459 return array_result; |
| 462 } | 460 } |
| 463 | 461 |
| 464 | 462 |
| 465 // ES#sec-regexp.prototype-@@split | 463 // ES#sec-regexp.prototype-@@split |
| 466 // RegExp.prototype [ @@split ] ( string, limit ) | 464 // RegExp.prototype [ @@split ] ( string, limit ) |
| 467 function RegExpSubclassSplit(string, limit) { | 465 function RegExpSubclassSplit(string, limit) { |
| 468 if (!IS_RECEIVER(this)) { | 466 if (!IS_RECEIVER(this)) { |
| 469 throw MakeTypeError(kIncompatibleMethodReceiver, | 467 throw %make_type_error(kIncompatibleMethodReceiver, |
| 470 "RegExp.prototype.@@split", this); | 468 "RegExp.prototype.@@split", this); |
| 471 } | 469 } |
| 472 string = TO_STRING(string); | 470 string = TO_STRING(string); |
| 473 var constructor = SpeciesConstructor(this, GlobalRegExp); | 471 var constructor = SpeciesConstructor(this, GlobalRegExp); |
| 474 var flags = TO_STRING(this.flags); | 472 var flags = TO_STRING(this.flags); |
| 475 | 473 |
| 476 // TODO(adamk): this fast path is wrong with respect to this.global | 474 // TODO(adamk): this fast path is wrong with respect to this.global |
| 477 // and this.sticky, but hopefully the spec will remove those gets | 475 // and this.sticky, but hopefully the spec will remove those gets |
| 478 // and thus make the assumption of 'exec' having no side-effects | 476 // and thus make the assumption of 'exec' having no side-effects |
| 479 // more correct. Also, we doesn't ensure that 'exec' is actually | 477 // more correct. Also, we doesn't ensure that 'exec' is actually |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 %_SubString(string, prevStringIndex, size)); | 533 %_SubString(string, prevStringIndex, size)); |
| 536 return array; | 534 return array; |
| 537 } | 535 } |
| 538 %FunctionRemovePrototype(RegExpSubclassSplit); | 536 %FunctionRemovePrototype(RegExpSubclassSplit); |
| 539 | 537 |
| 540 | 538 |
| 541 // ES#sec-regexp.prototype-@@match | 539 // ES#sec-regexp.prototype-@@match |
| 542 // RegExp.prototype [ @@match ] ( string ) | 540 // RegExp.prototype [ @@match ] ( string ) |
| 543 function RegExpSubclassMatch(string) { | 541 function RegExpSubclassMatch(string) { |
| 544 if (!IS_RECEIVER(this)) { | 542 if (!IS_RECEIVER(this)) { |
| 545 throw MakeTypeError(kIncompatibleMethodReceiver, | 543 throw %make_type_error(kIncompatibleMethodReceiver, |
| 546 "RegExp.prototype.@@match", this); | 544 "RegExp.prototype.@@match", this); |
| 547 } | 545 } |
| 548 string = TO_STRING(string); | 546 string = TO_STRING(string); |
| 549 var global = this.global; | 547 var global = this.global; |
| 550 if (!global) return RegExpSubclassExec(this, string); | 548 if (!global) return RegExpSubclassExec(this, string); |
| 551 var unicode = this.unicode; | 549 var unicode = this.unicode; |
| 552 this.lastIndex = 0; | 550 this.lastIndex = 0; |
| 553 var array = new InternalArray(); | 551 var array = new InternalArray(); |
| 554 var n = 0; | 552 var n = 0; |
| 555 var result; | 553 var result; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 | 691 |
| 694 result += replacement; // The add method converts to string if necessary. | 692 result += replacement; // The add method converts to string if necessary. |
| 695 // Can't use matchInfo any more from here, since the function could | 693 // Can't use matchInfo any more from here, since the function could |
| 696 // overwrite it. | 694 // overwrite it. |
| 697 return result + %_SubString(subject, endOfMatch, subject.length); | 695 return result + %_SubString(subject, endOfMatch, subject.length); |
| 698 } | 696 } |
| 699 | 697 |
| 700 | 698 |
| 701 function RegExpReplace(string, replace) { | 699 function RegExpReplace(string, replace) { |
| 702 if (!IS_REGEXP(this)) { | 700 if (!IS_REGEXP(this)) { |
| 703 throw MakeTypeError(kIncompatibleMethodReceiver, | 701 throw %make_type_error(kIncompatibleMethodReceiver, |
| 704 "RegExp.prototype.@@replace", this); | 702 "RegExp.prototype.@@replace", this); |
| 705 } | 703 } |
| 706 var subject = TO_STRING(string); | 704 var subject = TO_STRING(string); |
| 707 var search = this; | 705 var search = this; |
| 708 | 706 |
| 709 if (!IS_CALLABLE(replace)) { | 707 if (!IS_CALLABLE(replace)) { |
| 710 replace = TO_STRING(replace); | 708 replace = TO_STRING(replace); |
| 711 | 709 |
| 712 if (!REGEXP_GLOBAL(search)) { | 710 if (!REGEXP_GLOBAL(search)) { |
| 713 // Non-global regexp search, string replace. | 711 // Non-global regexp search, string replace. |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 var lastIndex = regexp.lastIndex; | 847 var lastIndex = regexp.lastIndex; |
| 850 regexp.lastIndex = lastIndex + | 848 regexp.lastIndex = lastIndex + |
| 851 AdvanceStringIndex(string, lastIndex, unicode); | 849 AdvanceStringIndex(string, lastIndex, unicode); |
| 852 } | 850 } |
| 853 | 851 |
| 854 | 852 |
| 855 // ES#sec-regexp.prototype-@@replace | 853 // ES#sec-regexp.prototype-@@replace |
| 856 // RegExp.prototype [ @@replace ] ( string, replaceValue ) | 854 // RegExp.prototype [ @@replace ] ( string, replaceValue ) |
| 857 function RegExpSubclassReplace(string, replace) { | 855 function RegExpSubclassReplace(string, replace) { |
| 858 if (!IS_RECEIVER(this)) { | 856 if (!IS_RECEIVER(this)) { |
| 859 throw MakeTypeError(kIncompatibleMethodReceiver, | 857 throw %make_type_error(kIncompatibleMethodReceiver, |
| 860 "RegExp.prototype.@@replace", this); | 858 "RegExp.prototype.@@replace", this); |
| 861 } | 859 } |
| 862 string = TO_STRING(string); | 860 string = TO_STRING(string); |
| 863 var length = string.length; | 861 var length = string.length; |
| 864 var functionalReplace = IS_CALLABLE(replace); | 862 var functionalReplace = IS_CALLABLE(replace); |
| 865 if (!functionalReplace) replace = TO_STRING(replace); | 863 if (!functionalReplace) replace = TO_STRING(replace); |
| 866 var global = TO_BOOLEAN(this.global); | 864 var global = TO_BOOLEAN(this.global); |
| 867 if (global) { | 865 if (global) { |
| 868 var unicode = TO_BOOLEAN(this.unicode); | 866 var unicode = TO_BOOLEAN(this.unicode); |
| 869 this.lastIndex = 0; | 867 this.lastIndex = 0; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 if (nextSourcePosition >= length) return accumulatedResult; | 932 if (nextSourcePosition >= length) return accumulatedResult; |
| 935 return accumulatedResult + %_SubString(string, nextSourcePosition, length); | 933 return accumulatedResult + %_SubString(string, nextSourcePosition, length); |
| 936 } | 934 } |
| 937 %FunctionRemovePrototype(RegExpSubclassReplace); | 935 %FunctionRemovePrototype(RegExpSubclassReplace); |
| 938 | 936 |
| 939 | 937 |
| 940 // ES#sec-regexp.prototype-@@search | 938 // ES#sec-regexp.prototype-@@search |
| 941 // RegExp.prototype [ @@search ] ( string ) | 939 // RegExp.prototype [ @@search ] ( string ) |
| 942 function RegExpSubclassSearch(string) { | 940 function RegExpSubclassSearch(string) { |
| 943 if (!IS_RECEIVER(this)) { | 941 if (!IS_RECEIVER(this)) { |
| 944 throw MakeTypeError(kIncompatibleMethodReceiver, | 942 throw %make_type_error(kIncompatibleMethodReceiver, |
| 945 "RegExp.prototype.@@search", this); | 943 "RegExp.prototype.@@search", this); |
| 946 } | 944 } |
| 947 string = TO_STRING(string); | 945 string = TO_STRING(string); |
| 948 var previousLastIndex = this.lastIndex; | 946 var previousLastIndex = this.lastIndex; |
| 949 this.lastIndex = 0; | 947 this.lastIndex = 0; |
| 950 var result = RegExpSubclassExec(this, string); | 948 var result = RegExpSubclassExec(this, string); |
| 951 this.lastIndex = previousLastIndex; | 949 this.lastIndex = previousLastIndex; |
| 952 if (IS_NULL(result)) return -1; | 950 if (IS_NULL(result)) return -1; |
| 953 return result.index; | 951 return result.index; |
| 954 } | 952 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 var matchEnd = RegExpLastMatchInfo[CAPTURE(index + 1)]; | 1010 var matchEnd = RegExpLastMatchInfo[CAPTURE(index + 1)]; |
| 1013 if (matchStart == -1 || matchEnd == -1) return ''; | 1011 if (matchStart == -1 || matchEnd == -1) return ''; |
| 1014 return %_SubString(LAST_SUBJECT(RegExpLastMatchInfo), matchStart, matchEnd); | 1012 return %_SubString(LAST_SUBJECT(RegExpLastMatchInfo), matchStart, matchEnd); |
| 1015 }; | 1013 }; |
| 1016 } | 1014 } |
| 1017 | 1015 |
| 1018 | 1016 |
| 1019 // ES6 21.2.5.3. | 1017 // ES6 21.2.5.3. |
| 1020 function RegExpGetFlags() { | 1018 function RegExpGetFlags() { |
| 1021 if (!IS_RECEIVER(this)) { | 1019 if (!IS_RECEIVER(this)) { |
| 1022 throw MakeTypeError( | 1020 throw %make_type_error( |
| 1023 kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this)); | 1021 kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this)); |
| 1024 } | 1022 } |
| 1025 var result = ''; | 1023 var result = ''; |
| 1026 if (this.global) result += 'g'; | 1024 if (this.global) result += 'g'; |
| 1027 if (this.ignoreCase) result += 'i'; | 1025 if (this.ignoreCase) result += 'i'; |
| 1028 if (this.multiline) result += 'm'; | 1026 if (this.multiline) result += 'm'; |
| 1029 if (this.unicode) result += 'u'; | 1027 if (this.unicode) result += 'u'; |
| 1030 if (this.sticky) result += 'y'; | 1028 if (this.sticky) result += 'y'; |
| 1031 return result; | 1029 return result; |
| 1032 } | 1030 } |
| 1033 | 1031 |
| 1034 | 1032 |
| 1035 // ES6 21.2.5.4. | 1033 // ES6 21.2.5.4. |
| 1036 function RegExpGetGlobal() { | 1034 function RegExpGetGlobal() { |
| 1037 if (!IS_REGEXP(this)) { | 1035 if (!IS_REGEXP(this)) { |
| 1038 // TODO(littledan): Remove this RegExp compat workaround | 1036 // TODO(littledan): Remove this RegExp compat workaround |
| 1039 if (this === GlobalRegExpPrototype) { | 1037 if (this === GlobalRegExpPrototype) { |
| 1040 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1038 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
| 1041 return UNDEFINED; | 1039 return UNDEFINED; |
| 1042 } | 1040 } |
| 1043 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.global"); | 1041 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.global"); |
| 1044 } | 1042 } |
| 1045 return TO_BOOLEAN(REGEXP_GLOBAL(this)); | 1043 return TO_BOOLEAN(REGEXP_GLOBAL(this)); |
| 1046 } | 1044 } |
| 1047 %SetForceInlineFlag(RegExpGetGlobal); | 1045 %SetForceInlineFlag(RegExpGetGlobal); |
| 1048 | 1046 |
| 1049 | 1047 |
| 1050 // ES6 21.2.5.5. | 1048 // ES6 21.2.5.5. |
| 1051 function RegExpGetIgnoreCase() { | 1049 function RegExpGetIgnoreCase() { |
| 1052 if (!IS_REGEXP(this)) { | 1050 if (!IS_REGEXP(this)) { |
| 1053 // TODO(littledan): Remove this RegExp compat workaround | 1051 // TODO(littledan): Remove this RegExp compat workaround |
| 1054 if (this === GlobalRegExpPrototype) { | 1052 if (this === GlobalRegExpPrototype) { |
| 1055 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1053 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
| 1056 return UNDEFINED; | 1054 return UNDEFINED; |
| 1057 } | 1055 } |
| 1058 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); | 1056 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); |
| 1059 } | 1057 } |
| 1060 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this)); | 1058 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this)); |
| 1061 } | 1059 } |
| 1062 | 1060 |
| 1063 | 1061 |
| 1064 // ES6 21.2.5.7. | 1062 // ES6 21.2.5.7. |
| 1065 function RegExpGetMultiline() { | 1063 function RegExpGetMultiline() { |
| 1066 if (!IS_REGEXP(this)) { | 1064 if (!IS_REGEXP(this)) { |
| 1067 // TODO(littledan): Remove this RegExp compat workaround | 1065 // TODO(littledan): Remove this RegExp compat workaround |
| 1068 if (this === GlobalRegExpPrototype) { | 1066 if (this === GlobalRegExpPrototype) { |
| 1069 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1067 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
| 1070 return UNDEFINED; | 1068 return UNDEFINED; |
| 1071 } | 1069 } |
| 1072 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.multiline"); | 1070 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.multiline"); |
| 1073 } | 1071 } |
| 1074 return TO_BOOLEAN(REGEXP_MULTILINE(this)); | 1072 return TO_BOOLEAN(REGEXP_MULTILINE(this)); |
| 1075 } | 1073 } |
| 1076 | 1074 |
| 1077 | 1075 |
| 1078 // ES6 21.2.5.10. | 1076 // ES6 21.2.5.10. |
| 1079 function RegExpGetSource() { | 1077 function RegExpGetSource() { |
| 1080 if (!IS_REGEXP(this)) { | 1078 if (!IS_REGEXP(this)) { |
| 1081 // TODO(littledan): Remove this RegExp compat workaround | 1079 // TODO(littledan): Remove this RegExp compat workaround |
| 1082 if (this === GlobalRegExpPrototype) { | 1080 if (this === GlobalRegExpPrototype) { |
| 1083 %IncrementUseCounter(kRegExpPrototypeSourceGetter); | 1081 %IncrementUseCounter(kRegExpPrototypeSourceGetter); |
| 1084 return "(?:)"; | 1082 return "(?:)"; |
| 1085 } | 1083 } |
| 1086 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.source"); | 1084 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.source"); |
| 1087 } | 1085 } |
| 1088 return REGEXP_SOURCE(this); | 1086 return REGEXP_SOURCE(this); |
| 1089 } | 1087 } |
| 1090 | 1088 |
| 1091 | 1089 |
| 1092 // ES6 21.2.5.12. | 1090 // ES6 21.2.5.12. |
| 1093 function RegExpGetSticky() { | 1091 function RegExpGetSticky() { |
| 1094 if (!IS_REGEXP(this)) { | 1092 if (!IS_REGEXP(this)) { |
| 1095 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it | 1093 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it |
| 1096 // TODO(littledan): Remove this workaround or standardize it | 1094 // TODO(littledan): Remove this workaround or standardize it |
| 1097 if (this === GlobalRegExpPrototype) { | 1095 if (this === GlobalRegExpPrototype) { |
| 1098 %IncrementUseCounter(kRegExpPrototypeStickyGetter); | 1096 %IncrementUseCounter(kRegExpPrototypeStickyGetter); |
| 1099 return UNDEFINED; | 1097 return UNDEFINED; |
| 1100 } | 1098 } |
| 1101 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.sticky"); | 1099 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.sticky"); |
| 1102 } | 1100 } |
| 1103 return TO_BOOLEAN(REGEXP_STICKY(this)); | 1101 return TO_BOOLEAN(REGEXP_STICKY(this)); |
| 1104 } | 1102 } |
| 1105 %SetForceInlineFlag(RegExpGetSticky); | 1103 %SetForceInlineFlag(RegExpGetSticky); |
| 1106 | 1104 |
| 1107 | 1105 |
| 1108 // ES6 21.2.5.15. | 1106 // ES6 21.2.5.15. |
| 1109 function RegExpGetUnicode() { | 1107 function RegExpGetUnicode() { |
| 1110 if (!IS_REGEXP(this)) { | 1108 if (!IS_REGEXP(this)) { |
| 1111 // TODO(littledan): Remove this RegExp compat workaround | 1109 // TODO(littledan): Remove this RegExp compat workaround |
| 1112 if (this === GlobalRegExpPrototype) { | 1110 if (this === GlobalRegExpPrototype) { |
| 1113 %IncrementUseCounter(kRegExpPrototypeUnicodeGetter); | 1111 %IncrementUseCounter(kRegExpPrototypeUnicodeGetter); |
| 1114 return UNDEFINED; | 1112 return UNDEFINED; |
| 1115 } | 1113 } |
| 1116 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.unicode"); | 1114 throw %make_type_error(kRegExpNonRegExp, "RegExp.prototype.unicode"); |
| 1117 } | 1115 } |
| 1118 return TO_BOOLEAN(REGEXP_UNICODE(this)); | 1116 return TO_BOOLEAN(REGEXP_UNICODE(this)); |
| 1119 } | 1117 } |
| 1120 %SetForceInlineFlag(RegExpGetUnicode); | 1118 %SetForceInlineFlag(RegExpGetUnicode); |
| 1121 | 1119 |
| 1122 | 1120 |
| 1123 function RegExpSpecies() { | 1121 function RegExpSpecies() { |
| 1124 return this; | 1122 return this; |
| 1125 } | 1123 } |
| 1126 | 1124 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 to.InternalRegExpMatch = InternalRegExpMatch; | 1223 to.InternalRegExpMatch = InternalRegExpMatch; |
| 1226 to.InternalRegExpReplace = InternalRegExpReplace; | 1224 to.InternalRegExpReplace = InternalRegExpReplace; |
| 1227 to.IsRegExp = IsRegExp; | 1225 to.IsRegExp = IsRegExp; |
| 1228 to.RegExpExec = DoRegExpExec; | 1226 to.RegExpExec = DoRegExpExec; |
| 1229 to.RegExpInitialize = RegExpInitialize; | 1227 to.RegExpInitialize = RegExpInitialize; |
| 1230 to.RegExpLastMatchInfo = RegExpLastMatchInfo; | 1228 to.RegExpLastMatchInfo = RegExpLastMatchInfo; |
| 1231 to.RegExpTest = RegExpTest; | 1229 to.RegExpTest = RegExpTest; |
| 1232 }); | 1230 }); |
| 1233 | 1231 |
| 1234 }) | 1232 }) |
| OLD | NEW |