| Index: src/builtins/builtins-regexp.cc
|
| diff --git a/src/builtins/builtins-regexp.cc b/src/builtins/builtins-regexp.cc
|
| index 259449e6015e056aa800ad56a844c063cb4a508a..33884d5e5ab3779730c9124f1070bf0cb81855a5 100644
|
| --- a/src/builtins/builtins-regexp.cc
|
| +++ b/src/builtins/builtins-regexp.cc
|
| @@ -698,24 +698,60 @@ void Builtins::Generate_RegExpPrototypeFlagsGetter(CodeAssemblerState* state) {
|
| }
|
|
|
| // ES6 21.2.5.10.
|
| -BUILTIN(RegExpPrototypeSourceGetter) {
|
| - HandleScope scope(isolate);
|
| +void Builtins::Generate_RegExpPrototypeSourceGetter(CodeAssemblerState* state) {
|
| + CodeStubAssembler a(state);
|
| + Node* const receiver = a.Parameter(0);
|
| + Node* const context = a.Parameter(3);
|
|
|
| - Handle<Object> recv = args.receiver();
|
| - if (!recv->IsJSRegExp()) {
|
| - Handle<JSFunction> regexp_fun = isolate->regexp_function();
|
| - if (*recv == regexp_fun->prototype()) {
|
| - isolate->CountUsage(v8::Isolate::kRegExpPrototypeSourceGetter);
|
| - return *isolate->factory()->NewStringFromAsciiChecked("(?:)");
|
| - }
|
| - THROW_NEW_ERROR_RETURN_FAILURE(
|
| - isolate, NewTypeError(MessageTemplate::kRegExpNonRegExp,
|
| - isolate->factory()->NewStringFromAsciiChecked(
|
| - "RegExp.prototype.source")));
|
| + // Check whether we have an unmodified regexp instance.
|
| + CLabel if_isjsregexp(&a), if_isnotjsregexp(&a, CLabel::kDeferred);
|
| +
|
| + a.GotoIf(a.TaggedIsSmi(receiver), &if_isnotjsregexp);
|
| + a.Branch(a.HasInstanceType(receiver, JS_REGEXP_TYPE), &if_isjsregexp,
|
| + &if_isnotjsregexp);
|
| +
|
| + a.Bind(&if_isjsregexp);
|
| + {
|
| + Node* const source = a.LoadObjectField(receiver, JSRegExp::kSourceOffset);
|
| + a.Return(source);
|
| }
|
|
|
| - Handle<JSRegExp> regexp = Handle<JSRegExp>::cast(recv);
|
| - return regexp->source();
|
| + a.Bind(&if_isnotjsregexp);
|
| + {
|
| + Isolate* isolate = a.isolate();
|
| + Node* const native_context = a.LoadNativeContext(context);
|
| + Node* const regexp_fun =
|
| + a.LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX);
|
| + Node* const initial_map =
|
| + a.LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset);
|
| + Node* const initial_prototype = a.LoadMapPrototype(initial_map);
|
| +
|
| + CLabel if_isprototype(&a), if_isnotprototype(&a);
|
| + a.Branch(a.WordEqual(receiver, initial_prototype), &if_isprototype,
|
| + &if_isnotprototype);
|
| +
|
| + a.Bind(&if_isprototype);
|
| + {
|
| + const int counter = v8::Isolate::kRegExpPrototypeSourceGetter;
|
| + Node* const counter_smi = a.SmiConstant(counter);
|
| + a.CallRuntime(Runtime::kIncrementUseCounter, context, counter_smi);
|
| +
|
| + Node* const result =
|
| + a.HeapConstant(isolate->factory()->NewStringFromAsciiChecked("(?:)"));
|
| + a.Return(result);
|
| + }
|
| +
|
| + a.Bind(&if_isnotprototype);
|
| + {
|
| + Node* const message_id =
|
| + a.SmiConstant(Smi::FromInt(MessageTemplate::kRegExpNonRegExp));
|
| + Node* const method_name_str =
|
| + a.HeapConstant(isolate->factory()->NewStringFromAsciiChecked(
|
| + "RegExp.prototype.source"));
|
| + a.TailCallRuntime(Runtime::kThrowTypeError, context, message_id,
|
| + method_name_str);
|
| + }
|
| + }
|
| }
|
|
|
| BUILTIN(RegExpPrototypeToString) {
|
| @@ -756,9 +792,11 @@ BUILTIN(RegExpPrototypeToString) {
|
| }
|
|
|
| // ES6 21.2.4.2.
|
| -BUILTIN(RegExpPrototypeSpeciesGetter) {
|
| - HandleScope scope(isolate);
|
| - return *args.receiver();
|
| +void Builtins::Generate_RegExpPrototypeSpeciesGetter(
|
| + CodeAssemblerState* state) {
|
| + CodeStubAssembler a(state);
|
| + Node* const receiver = a.Parameter(0);
|
| + a.Return(receiver);
|
| }
|
|
|
| namespace {
|
|
|