Index: src/js/regexp.js |
diff --git a/src/js/regexp.js b/src/js/regexp.js |
index 55466dc03dd3a1e323d263e8473ea0c2023474cd..4a5c7033e92a4b516f65c4f4a546e8842032cc58 100644 |
--- a/src/js/regexp.js |
+++ b/src/js/regexp.js |
@@ -16,6 +16,7 @@ var InternalArray = utils.InternalArray; |
var InternalPackedArray = utils.InternalPackedArray; |
var MakeTypeError; |
var splitSymbol = utils.ImportNow("split_symbol"); |
+var matchSymbol = utils.ImportNow("match_symbol");; |
utils.ImportFromExperimental(function(from) { |
FLAG_harmony_tolength = from.FLAG_harmony_tolength; |
@@ -43,61 +44,75 @@ var RegExpLastMatchInfo = new InternalPackedArray( |
// ------------------------------------------------------------------- |
-// A recursive descent parser for Patterns according to the grammar of |
-// ECMA-262 15.10.1, with deviations noted below. |
-function DoConstructRegExp(object, pattern, flags) { |
- // RegExp : Called as constructor; see ECMA-262, section 15.10.4. |
- if (IS_REGEXP(pattern)) { |
- if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags); |
- flags = (REGEXP_GLOBAL(pattern) ? 'g' : '') |
- + (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') |
- + (REGEXP_MULTILINE(pattern) ? 'm' : '') |
- + (REGEXP_UNICODE(pattern) ? 'u' : '') |
- + (REGEXP_STICKY(pattern) ? 'y' : ''); |
- pattern = REGEXP_SOURCE(pattern); |
- } |
+function IsRegExp(o) { |
+ if (!IS_OBJECT(o)) return false; |
+ var is_regexp = o[matchSymbol]; |
+ if (!IS_UNDEFINED(is_regexp)) return TO_BOOLEAN(is_regexp); |
+ return IS_REGEXP(o); |
+} |
+ |
+// ES6 section 21.2.3.2.2 |
+function RegExpInitialize(object, pattern, flags) { |
pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern); |
flags = IS_UNDEFINED(flags) ? '' : TO_STRING(flags); |
- |
%RegExpInitializeAndCompile(object, pattern, flags); |
+ return object; |
+} |
+ |
+ |
+function PatternFlags(pattern) { |
+ return (REGEXP_GLOBAL(pattern) ? 'g' : '') + |
+ (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') + |
+ (REGEXP_MULTILINE(pattern) ? 'm' : '') + |
+ (REGEXP_UNICODE(pattern) ? 'u' : '') + |
+ (REGEXP_STICKY(pattern) ? 'y' : ''); |
} |
function RegExpConstructor(pattern, flags) { |
- if (%_IsConstructCall()) { |
- DoConstructRegExp(this, pattern, flags); |
- } else { |
- // RegExp : Called as function; see ECMA-262, section 15.10.3.1. |
- if (IS_REGEXP(pattern) && IS_UNDEFINED(flags)) { |
+ var newtarget = new.target; |
+ var pattern_is_regexp = IsRegExp(pattern); |
+ |
+ if (IS_UNDEFINED(newtarget)) { |
+ newtarget = GlobalRegExp; |
+ |
+ // ES6 section 21.2.3.1 step 3.b |
+ if (pattern_is_regexp && IS_UNDEFINED(flags) && |
+ pattern.constructor === newtarget) { |
return pattern; |
} |
- return new GlobalRegExp(pattern, flags); |
} |
+ |
+ if (IS_REGEXP(pattern)) { |
+ if (IS_UNDEFINED(flags)) flags = PatternFlags(pattern); |
+ pattern = REGEXP_SOURCE(pattern); |
+ |
+ } else if (pattern_is_regexp) { |
+ var input_pattern = pattern; |
+ pattern = pattern.source; |
+ if (IS_UNDEFINED(flags)) flags = input_pattern.flags; |
+ } |
+ |
+ var object = %NewObject(GlobalRegExp, newtarget); |
+ return RegExpInitialize(object, pattern, flags); |
} |
-// Deprecated RegExp.prototype.compile method. We behave like the constructor |
-// were called again. In SpiderMonkey, this method returns the regexp object. |
-// In JSC, it returns undefined. For compatibility with JSC, we match their |
-// behavior. |
+ |
function RegExpCompileJS(pattern, flags) { |
- // Both JSC and SpiderMonkey treat a missing pattern argument as the |
- // empty subject string, and an actual undefined value passed as the |
- // pattern as the string 'undefined'. Note that JSC is inconsistent |
- // here, treating undefined values differently in |
- // RegExp.prototype.compile and in the constructor, where they are |
- // the empty string. For compatibility with JSC, we match their |
- // behavior. |
- if (this == GlobalRegExp.prototype) { |
- // We don't allow recompiling RegExp.prototype. |
+ if (!IS_REGEXP(this)) { |
throw MakeTypeError(kIncompatibleMethodReceiver, |
- 'RegExp.prototype.compile', this); |
+ "RegExp.prototype.compile", this); |
} |
- if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) { |
- DoConstructRegExp(this, 'undefined', flags); |
- } else { |
- DoConstructRegExp(this, pattern, flags); |
+ |
+ if (IS_REGEXP(pattern)) { |
+ if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags); |
+ |
+ flags = PatternFlags(pattern); |
+ pattern = REGEXP_SOURCE(pattern); |
} |
+ |
+ return RegExpInitialize(this, pattern, flags); |
} |