Modified: trunk/LayoutTests/fast/regex/constructor-expected.txt (199105 => 199106)
--- trunk/LayoutTests/fast/regex/constructor-expected.txt 2016-04-06 17:44:42 UTC (rev 199105)
+++ trunk/LayoutTests/fast/regex/constructor-expected.txt 2016-04-06 18:26:11 UTC (rev 199106)
@@ -5,7 +5,7 @@
PASS re === RegExp(re) is true
PASS re !== new RegExp(re) is true
-PASS re === RegExp(re,'i') is true
+PASS re !== RegExp(re,'i') is true
PASS re !== new RegExp(re,'i') is true
PASS successfullyParsed is true
Modified: trunk/LayoutTests/fast/regex/script-tests/constructor.js (199105 => 199106)
--- trunk/LayoutTests/fast/regex/script-tests/constructor.js 2016-04-06 17:44:42 UTC (rev 199105)
+++ trunk/LayoutTests/fast/regex/script-tests/constructor.js 2016-04-06 18:26:11 UTC (rev 199106)
@@ -4,6 +4,6 @@
shouldBeTrue("re === RegExp(re)");
shouldBeTrue("re !== new RegExp(re)");
-shouldBeTrue("re === RegExp(re,'i')");
+shouldBeTrue("re !== RegExp(re,'i')");
shouldBeTrue("re !== new RegExp(re,'i')");
Modified: trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp (199105 => 199106)
--- trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp 2016-04-06 17:44:42 UTC (rev 199105)
+++ trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp 2016-04-06 18:26:11 UTC (rev 199106)
@@ -96,7 +96,6 @@
Base::finishCreation(vm, ASCIILiteral("RegExp"));
ASSERT(inherits(info()));
- // ECMA 15.10.5.1 RegExp.prototype
putDirectWithoutTransition(vm, vm.propertyNames->prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
@@ -260,47 +259,74 @@
return structure;
}
-// ECMA 15.10.4
-JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, JSValue newTarget)
+inline RegExpFlags toFlags(ExecState* exec, JSValue flags)
{
- JSValue arg0 = args.at(0);
- JSValue arg1 = args.at(1);
+ if (flags.isUndefined())
+ return NoFlags;
+ JSString* flagsString = flags.toString(exec);
+ if (!flagsString) {
+ ASSERT(exec->hadException());
+ return InvalidFlags;
+ }
+ RegExpFlags result = regExpFlags(flagsString->value(exec));
+ if (exec->hadException())
+ return InvalidFlags;
+ if (result == InvalidFlags)
+ throwSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor."));
+ return result;
+}
+
+JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, JSObject* callee, JSValue newTarget)
+{
VM& vm = exec->vm();
- RegExpFlags flags = NoFlags;
- bool haveFlags = false;
- if (!arg1.isUndefined()) {
- flags = regExpFlags(arg1.toString(exec)->value(exec));
+ JSValue patternArg = args.at(0);
+ JSValue flagsArg = args.at(1);
+
+ bool isPatternRegExp = patternArg.inherits(RegExpObject::info());
+ bool constructAsRegexp = isRegExp(vm, exec, patternArg);
+
+ if (newTarget.isUndefined() && constructAsRegexp && flagsArg.isUndefined()) {
+ JSValue constructor = patternArg.get(exec, vm.propertyNames->constructor);
if (vm.exception())
- return 0;
- if (flags == InvalidFlags)
- return vm.throwException(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
- haveFlags = true;
+ return nullptr;
+ if (callee == constructor) {
+ // We know that patternArg is a object otherwise constructAsRegexp would be false.
+ return patternArg.getObject();
+ }
}
- if (arg0.inherits(RegExpObject::info())) {
- // If called as a function, this just returns the first argument (see 15.10.3.1).
- if (newTarget != jsUndefined()) {
- RegExp* regExp = static_cast<RegExpObject*>(asObject(arg0))->regExp();
- Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
- if (vm.exception())
+ if (isPatternRegExp) {
+ RegExp* regExp = jsCast<RegExpObject*>(patternArg)->regExp();
+ Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
+ if (exec->hadException())
+ return nullptr;
+
+ if (!flagsArg.isUndefined()) {
+ RegExpFlags flags = toFlags(exec, flagsArg);
+ if (flags == InvalidFlags)
return nullptr;
+ regExp = RegExp::create(vm, regExp->pattern(), flags);
+ }
- if (haveFlags) {
- regExp = RegExp::create(vm, regExp->pattern(), flags);
- if (vm.exception())
- return nullptr;
- }
+ return RegExpObject::create(exec->vm(), structure, regExp);
+ }
- return RegExpObject::create(vm, structure, regExp);
- }
- return asObject(arg0);
+ if (constructAsRegexp) {
+ JSValue pattern = patternArg.get(exec, vm.propertyNames->source);
+ if (flagsArg.isUndefined())
+ flagsArg = patternArg.get(exec, vm.propertyNames->flags);
+ patternArg = pattern;
}
- String pattern = arg0.isUndefined() ? emptyString() : arg0.toString(exec)->value(exec);
- if (vm.exception())
- return 0;
+ String pattern = patternArg.isUndefined() ? emptyString() : patternArg.toString(exec)->value(exec);
+ if (exec->hadException())
+ return nullptr;
+ RegExpFlags flags = toFlags(exec, flagsArg);
+ if (flags == InvalidFlags)
+ return nullptr;
+
RegExp* regExp = RegExp::create(vm, pattern, flags);
if (!regExp->isValid())
return vm.throwException(exec, createSyntaxError(exec, regExp->errorMessage()));
@@ -314,7 +340,7 @@
static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args, exec->newTarget()));
+ return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args, exec->callee(), exec->newTarget()));
}
ConstructType RegExpConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -323,11 +349,10 @@
return ConstructType::Host;
}
-// ECMA 15.10.3
static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args));
+ return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args, exec->callee()));
}
CallType RegExpConstructor::getCallData(JSCell*, CallData& callData)
Modified: trunk/Source/_javascript_Core/runtime/RegExpConstructor.h (199105 => 199106)
--- trunk/Source/_javascript_Core/runtime/RegExpConstructor.h 2016-04-06 17:44:42 UTC (rev 199105)
+++ trunk/Source/_javascript_Core/runtime/RegExpConstructor.h 2016-04-06 18:26:11 UTC (rev 199106)
@@ -87,7 +87,7 @@
RegExpConstructor* asRegExpConstructor(JSValue);
-JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, JSValue newTarget = jsUndefined());
+JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, JSObject* callee = nullptr, JSValue newTarget = jsUndefined());
inline RegExpConstructor* asRegExpConstructor(JSValue value)
{