Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/builtins/builtins-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
| 6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
| 7 | 7 |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/regexp/jsregexp.h" | 9 #include "src/regexp/jsregexp.h" |
| 10 #include "src/regexp/regexp-utils.h" | 10 #include "src/regexp/regexp-utils.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 } | 60 } |
| 61 | 61 |
| 62 // TODO(jgruber): We could avoid the flags back and forth conversions. | 62 // TODO(jgruber): We could avoid the flags back and forth conversions. |
| 63 RETURN_RESULT(isolate, | 63 RETURN_RESULT(isolate, |
| 64 JSRegExp::Initialize(regexp, pattern_string, flags_string), | 64 JSRegExp::Initialize(regexp, pattern_string, flags_string), |
| 65 JSRegExp); | 65 JSRegExp); |
| 66 } | 66 } |
| 67 | 67 |
| 68 } // namespace | 68 } // namespace |
| 69 | 69 |
| 70 BUILTIN(RegExpInitialize) { | |
| 71 HandleScope scope(isolate); | |
| 72 Handle<JSRegExp> regexp = args.at<JSRegExp>(1); | |
| 73 Handle<Object> pattern = args.atOrUndefined(isolate, 2); | |
| 74 Handle<Object> flags = args.atOrUndefined(isolate, 3); | |
| 75 RETURN_RESULT_OR_FAILURE(isolate, | |
| 76 RegExpInitialize(isolate, regexp, pattern, flags)); | |
| 77 } | |
| 78 | |
| 79 BUILTIN(RegExpIsRegExp) { | |
| 80 HandleScope scope(isolate); | |
| 81 Handle<Object> object = args.at<Object>(1); | |
| 82 | |
| 83 Maybe<bool> maybe_is_regexp = RegExpUtils::IsRegExp(isolate, object); | |
| 84 if (maybe_is_regexp.IsNothing()) { | |
| 85 DCHECK(isolate->has_pending_exception()); | |
| 86 return isolate->heap()->exception(); | |
| 87 } | |
| 88 | |
| 89 return isolate->heap()->ToBoolean(maybe_is_regexp.FromJust()); | |
| 90 } | |
| 91 | |
| 70 // ES#sec-regexp-pattern-flags | 92 // ES#sec-regexp-pattern-flags |
| 71 // RegExp ( pattern, flags ) | 93 // RegExp ( pattern, flags ) |
| 72 BUILTIN(RegExpConstructor) { | 94 BUILTIN(RegExpConstructor) { |
| 73 HandleScope scope(isolate); | 95 HandleScope scope(isolate); |
| 74 | 96 |
| 75 Handle<HeapObject> new_target = args.new_target(); | 97 Handle<HeapObject> new_target = args.new_target(); |
| 76 Handle<Object> pattern = args.atOrUndefined(isolate, 1); | 98 Handle<Object> pattern = args.atOrUndefined(isolate, 1); |
| 77 Handle<Object> flags = args.atOrUndefined(isolate, 2); | 99 Handle<Object> flags = args.atOrUndefined(isolate, 2); |
| 78 | 100 |
| 79 Handle<JSFunction> target = isolate->regexp_function(); | 101 Handle<JSFunction> target = isolate->regexp_function(); |
| (...skipping 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1648 } | 1670 } |
| 1649 | 1671 |
| 1650 a->Bind(&runtime); | 1672 a->Bind(&runtime); |
| 1651 { | 1673 { |
| 1652 Node* const result = a->CallRuntime(Runtime::kRegExpReplace, context, | 1674 Node* const result = a->CallRuntime(Runtime::kRegExpReplace, context, |
| 1653 receiver, string, replace_value); | 1675 receiver, string, replace_value); |
| 1654 a->Return(result); | 1676 a->Return(result); |
| 1655 } | 1677 } |
| 1656 } | 1678 } |
| 1657 | 1679 |
| 1680 namespace { | |
| 1681 | |
| 1682 // TODO(jgruber): Replace this with a FixedArray. | |
| 1683 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
| |
| 1684 compiler::Node* context) { | |
| 1685 typedef compiler::Node Node; | |
| 1686 | |
| 1687 const ElementsKind elements_kind = FAST_ELEMENTS; | |
| 1688 Node* const native_context = a->LoadNativeContext(context); | |
| 1689 Node* const array_map = | |
| 1690 a->LoadJSArrayElementsMap(elements_kind, native_context); | |
| 1691 Node* const capacity = a->IntPtrConstant(RegExpImpl::kLastMatchOverhead + 2); | |
| 1692 Node* const allocation_site = nullptr; | |
| 1693 | |
| 1694 return a->AllocateJSArray(elements_kind, array_map, capacity, capacity, | |
| 1695 allocation_site, | |
| 1696 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 1697 } | |
| 1698 | |
| 1699 } // namespace | |
| 1700 | |
| 1701 // Simple string matching functionality for internal use which does not modify | |
| 1702 // the last match info. | |
| 1703 void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) { | |
| 1704 typedef CodeStubAssembler::Label Label; | |
| 1705 typedef compiler::Node Node; | |
| 1706 | |
| 1707 Isolate* const isolate = a->isolate(); | |
| 1708 | |
| 1709 Node* const regexp = a->Parameter(1); | |
| 1710 Node* const string = a->Parameter(2); | |
| 1711 Node* const context = a->Parameter(5); | |
| 1712 | |
| 1713 Node* const null = a->NullConstant(); | |
| 1714 Node* const smi_zero = a->SmiConstant(Smi::FromInt(0)); | |
| 1715 Node* const internal_match_info = GetInternalMatchInfo(a, context); | |
| 1716 | |
| 1717 Callable exec_callable = CodeFactory::RegExpExec(isolate); | |
| 1718 Node* const match_indices = a->CallStub( | |
| 1719 exec_callable, context, regexp, string, smi_zero, internal_match_info); | |
| 1720 | |
| 1721 Label if_matched(a), if_didnotmatch(a); | |
| 1722 a->Branch(a->WordEqual(match_indices, null), &if_didnotmatch, &if_matched); | |
| 1723 | |
| 1724 a->Bind(&if_didnotmatch); | |
| 1725 a->Return(null); | |
| 1726 | |
| 1727 a->Bind(&if_matched); | |
| 1728 { | |
| 1729 Node* const match_elements = a->LoadElements(match_indices); | |
| 1730 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, | |
| 1731 match_elements, string); | |
| 1732 a->Return(result); | |
| 1733 } | |
| 1734 } | |
| 1735 | |
| 1736 // Simple string replacement functionality for internal use which does not | |
| 1737 // modify the last match info. | |
| 1738 void Builtins::Generate_RegExpInternalReplace(CodeStubAssembler* a) { | |
| 1739 typedef compiler::Node Node; | |
| 1740 | |
| 1741 Node* const regexp = a->Parameter(1); | |
| 1742 Node* const subject_string = a->Parameter(2); | |
| 1743 Node* const replace_string = a->Parameter(3); | |
| 1744 Node* const context = a->Parameter(6); | |
| 1745 | |
| 1746 Node* const internal_match_info = GetInternalMatchInfo(a, context); | |
| 1747 | |
| 1748 Node* const result = a->CallRuntime( | |
| 1749 Runtime::kStringReplaceGlobalRegExpWithString, context, subject_string, | |
| 1750 regexp, replace_string, internal_match_info); | |
| 1751 a->Return(result); | |
| 1752 } | |
| 1753 | |
| 1658 } // namespace internal | 1754 } // namespace internal |
| 1659 } // namespace v8 | 1755 } // namespace v8 |
| OLD | NEW |