| 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); | 
| } | 
|  | 
|  | 
|  |