Commit 836299aa authored by jgruber's avatar jgruber Committed by Commit bot

[regexp] Port RegExpCompile and RegExpToString

BUG=v8:5339

Review-Url: https://codereview.chromium.org/2295273003
Cr-Commit-Position: refs/heads/master@{#39119}
parent 628e9e3e
......@@ -1636,6 +1636,12 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Builtins::kRegExpPrototypeStickyGetter, false);
SimpleInstallGetter(proto, factory->unicode_string(),
Builtins::kRegExpPrototypeUnicodeGetter, false);
SimpleInstallFunction(proto, "compile", Builtins::kRegExpPrototypeCompile,
2, false, DONT_ENUM);
SimpleInstallFunction(proto, factory->toString_string(),
Builtins::kRegExpPrototypeToString, 0, false,
DONT_ENUM);
}
{
......
......@@ -148,6 +148,36 @@ BUILTIN(RegExpConstructor) {
RegExpInitialize(isolate, regexp, pattern, flags));
}
BUILTIN(RegExpPrototypeCompile) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSRegExp, regexp, "RegExp.prototype.compile");
Handle<Object> pattern = args.atOrUndefined(isolate, 1);
Handle<Object> flags = args.atOrUndefined(isolate, 2);
if (pattern->IsJSRegExp()) {
Handle<JSRegExp> pattern_regexp = Handle<JSRegExp>::cast(pattern);
if (!flags->IsUndefined(isolate)) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kRegExpFlags));
}
flags = PatternFlags(isolate, pattern_regexp);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, pattern,
Object::GetProperty(pattern, isolate->factory()->source_string()));
}
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, regexp, RegExpInitialize(isolate, regexp, pattern, flags));
// Return undefined for compatibility with JSC.
// See http://crbug.com/585775 for web compat details.
return isolate->heap()->undefined_value();
}
#define APPEND_CHAR_FOR_FLAG(flag, c) \
do { \
Handle<Object> property; \
......@@ -199,6 +229,43 @@ BUILTIN(RegExpPrototypeSourceGetter) {
return regexp->source();
}
BUILTIN(RegExpPrototypeToString) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.toString");
if (*recv == isolate->regexp_function()->prototype()) {
isolate->CountUsage(v8::Isolate::kRegExpPrototypeToString);
}
IncrementalStringBuilder builder(isolate);
builder.AppendCharacter('/');
{
Handle<Object> source;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, source,
JSReceiver::GetProperty(recv, isolate->factory()->source_string()));
Handle<String> source_str;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, source_str,
Object::ToString(isolate, source));
builder.AppendString(source_str);
}
builder.AppendCharacter('/');
{
Handle<Object> flags;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, flags,
JSReceiver::GetProperty(recv, isolate->factory()->flags_string()));
Handle<String> flags_str;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, flags_str,
Object::ToString(isolate, flags));
builder.AppendString(flags_str);
}
RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
}
// ES6 21.2.4.2.
BUILTIN(RegExpPrototypeSpeciesGetter) {
HandleScope scope(isolate);
......
......@@ -491,6 +491,8 @@ namespace internal {
\
/* RegExp */ \
CPP(RegExpConstructor) \
CPP(RegExpPrototypeCompile) \
CPP(RegExpPrototypeToString) \
CPP(RegExpPrototypeCapture1Getter) \
CPP(RegExpPrototypeCapture2Getter) \
CPP(RegExpPrototypeCapture3Getter) \
......
......@@ -71,36 +71,6 @@ function RegExpInitialize(object, pattern, flags) {
}
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' : '');
}
// ES#sec-regexp.prototype.compile RegExp.prototype.compile (pattern, flags)
function RegExpCompileJS(pattern, flags) {
if (!IS_REGEXP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
"RegExp.prototype.compile", this);
}
if (IS_REGEXP(pattern)) {
if (!IS_UNDEFINED(flags)) throw %make_type_error(kRegExpFlags);
flags = PatternFlags(pattern);
pattern = REGEXP_SOURCE(pattern);
}
RegExpInitialize(this, pattern, flags);
// Return undefined for compatibility with JSC.
// See http://crbug.com/585775 for web compat details.
}
function DoRegExpExec(regexp, string, index) {
return %_RegExpExec(regexp, string, index, RegExpLastMatchInfo);
}
......@@ -335,18 +305,6 @@ function TrimRegExp(regexp) {
}
function RegExpToString() {
if (!IS_RECEIVER(this)) {
throw %make_type_error(
kIncompatibleMethodReceiver, 'RegExp.prototype.toString', this);
}
if (this === GlobalRegExp.prototype) {
%IncrementUseCounter(kRegExpPrototypeToString);
}
return '/' + TO_STRING(this.source) + '/' + TO_STRING(this.flags);
}
function AtSurrogatePair(subject, index) {
if (index + 1 >= subject.length) return false;
var first = %_StringCharCodeAt(subject, index);
......@@ -929,8 +887,6 @@ function RegExpSubclassSearch(string) {
utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [
"exec", RegExpSubclassExecJS,
"test", RegExpSubclassTest,
"toString", RegExpToString,
"compile", RegExpCompileJS,
matchSymbol, RegExpSubclassMatch,
replaceSymbol, RegExpSubclassReplace,
searchSymbol, RegExpSubclassSearch,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment