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 |