Chromium Code Reviews| Index: src/builtins/builtins-regexp.cc |
| diff --git a/src/builtins/builtins-regexp.cc b/src/builtins/builtins-regexp.cc |
| index 831df35d964f5106aafe4d567cf1f60198a8979a..14e6568fb6e177fb3e6df7578ff823855b86dc79 100644 |
| --- a/src/builtins/builtins-regexp.cc |
| +++ b/src/builtins/builtins-regexp.cc |
| @@ -67,6 +67,28 @@ MaybeHandle<JSRegExp> RegExpInitialize(Isolate* isolate, |
| } // namespace |
| +BUILTIN(RegExpInitialize) { |
| + HandleScope scope(isolate); |
| + Handle<JSRegExp> regexp = args.at<JSRegExp>(1); |
| + Handle<Object> pattern = args.atOrUndefined(isolate, 2); |
| + Handle<Object> flags = args.atOrUndefined(isolate, 3); |
| + RETURN_RESULT_OR_FAILURE(isolate, |
| + RegExpInitialize(isolate, regexp, pattern, flags)); |
| +} |
| + |
| +BUILTIN(RegExpIsRegExp) { |
| + HandleScope scope(isolate); |
| + Handle<Object> object = args.at<Object>(1); |
| + |
| + Maybe<bool> maybe_is_regexp = RegExpUtils::IsRegExp(isolate, object); |
| + if (maybe_is_regexp.IsNothing()) { |
| + DCHECK(isolate->has_pending_exception()); |
| + return isolate->heap()->exception(); |
| + } |
| + |
| + return isolate->heap()->ToBoolean(maybe_is_regexp.FromJust()); |
| +} |
| + |
| // ES#sec-regexp-pattern-flags |
| // RegExp ( pattern, flags ) |
| BUILTIN(RegExpConstructor) { |
| @@ -1655,5 +1677,79 @@ void Builtins::Generate_RegExpPrototypeReplace(CodeStubAssembler* a) { |
| } |
| } |
| +namespace { |
| + |
| +// TODO(jgruber): Replace this with a FixedArray. |
| +compiler::Node* GetInternalMatchInfo(CodeStubAssembler* a, |
|
Yang
2016/10/13 11:51:11
This allocates a new array on every invocation. I
jgruber
2016/10/13 12:02:37
Sure. I'll take care of it once the FixedArray con
|
| + compiler::Node* context) { |
| + typedef compiler::Node Node; |
| + |
| + const ElementsKind elements_kind = FAST_ELEMENTS; |
| + Node* const native_context = a->LoadNativeContext(context); |
| + Node* const array_map = |
| + a->LoadJSArrayElementsMap(elements_kind, native_context); |
| + Node* const capacity = a->IntPtrConstant(RegExpImpl::kLastMatchOverhead + 2); |
| + Node* const allocation_site = nullptr; |
| + |
| + return a->AllocateJSArray(elements_kind, array_map, capacity, capacity, |
| + allocation_site, |
| + CodeStubAssembler::INTPTR_PARAMETERS); |
| +} |
| + |
| +} // namespace |
| + |
| +// Simple string matching functionality for internal use which does not modify |
| +// the last match info. |
| +void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) { |
| + typedef CodeStubAssembler::Label Label; |
| + typedef compiler::Node Node; |
| + |
| + Isolate* const isolate = a->isolate(); |
| + |
| + Node* const regexp = a->Parameter(1); |
| + Node* const string = a->Parameter(2); |
| + Node* const context = a->Parameter(5); |
| + |
| + Node* const null = a->NullConstant(); |
| + Node* const smi_zero = a->SmiConstant(Smi::FromInt(0)); |
| + Node* const internal_match_info = GetInternalMatchInfo(a, context); |
| + |
| + Callable exec_callable = CodeFactory::RegExpExec(isolate); |
| + Node* const match_indices = a->CallStub( |
| + exec_callable, context, regexp, string, smi_zero, internal_match_info); |
| + |
| + Label if_matched(a), if_didnotmatch(a); |
| + a->Branch(a->WordEqual(match_indices, null), &if_didnotmatch, &if_matched); |
| + |
| + a->Bind(&if_didnotmatch); |
| + a->Return(null); |
| + |
| + a->Bind(&if_matched); |
| + { |
| + Node* const match_elements = a->LoadElements(match_indices); |
| + Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, |
| + match_elements, string); |
| + a->Return(result); |
| + } |
| +} |
| + |
| +// Simple string replacement functionality for internal use which does not |
| +// modify the last match info. |
| +void Builtins::Generate_RegExpInternalReplace(CodeStubAssembler* a) { |
| + typedef compiler::Node Node; |
| + |
| + Node* const regexp = a->Parameter(1); |
| + Node* const subject_string = a->Parameter(2); |
| + Node* const replace_string = a->Parameter(3); |
| + Node* const context = a->Parameter(6); |
| + |
| + Node* const internal_match_info = GetInternalMatchInfo(a, context); |
| + |
| + Node* const result = a->CallRuntime( |
| + Runtime::kStringReplaceGlobalRegExpWithString, context, subject_string, |
| + regexp, replace_string, internal_match_info); |
| + a->Return(result); |
| +} |
| + |
| } // namespace internal |
| } // namespace v8 |