1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecmascript/compiler/builtins/builtins_regexp_stub_builder.h"
17 #include "ecmascript/compiler/new_object_stub_builder.h"
18 #include "ecmascript/regexp/regexp_parser.h"
19 namespace panda::ecmascript::kungfu {
20
GetFlags(GateRef glue,GateRef thisValue,GateRef numArgs,Variable * result,Label * exit,Label * slowPath)21 void BuiltinsRegExpStubBuilder::GetFlags(GateRef glue, GateRef thisValue,
22 [[maybe_unused]] GateRef numArgs, Variable* result, Label* exit, Label *slowPath)
23 {
24 auto env = GetEnvironment();
25 Label isEcmaObject(env);
26 BRANCH(IsEcmaObject(thisValue), &isEcmaObject, slowPath);
27 Bind(&isEcmaObject);
28 Label fastRegExpPath(env);
29 GateRef fastRegExp = CallNGCRuntime(glue, RTSTUB_ID(IsFastRegExp), {glue, thisValue});
30 BRANCH(fastRegExp, slowPath, &fastRegExpPath);
31 Bind(&fastRegExpPath);
32 {
33 Label hasException(env);
34 DEFVARIABLE(bitFlagsStr, VariableType::INT32(), Int32(0));
35 GateRef globalResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::GLOBAL_STRING_INDEX);
36 Label notHasException(env);
37 BRANCH(HasPendingException(glue), &hasException, ¬HasException);
38 Bind(¬HasException);
39 Label globalKey(env);
40 Label notGlobalKey(env);
41 BRANCH(TaggedIsTrue(globalResult), &globalKey, ¬GlobalKey);
42 Bind(&globalKey);
43 {
44 bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_GLOBAL));
45 Jump(¬GlobalKey);
46 }
47 Bind(¬GlobalKey);
48 GateRef ignoreCaseResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::IGNORE_CASE_INDEX);
49 Label notHasException1(env);
50 BRANCH(HasPendingException(glue), &hasException, ¬HasException1);
51 Bind(¬HasException1);
52 Label ignoreCaseKey(env);
53 Label notIgnoreCaseKey(env);
54 BRANCH(TaggedIsTrue(ignoreCaseResult), &ignoreCaseKey, ¬IgnoreCaseKey);
55 Bind(&ignoreCaseKey);
56 {
57 bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_IGNORECASE));
58 Jump(¬IgnoreCaseKey);
59 }
60 Bind(¬IgnoreCaseKey);
61 GateRef multilineResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::MULTILINE_INDEX);
62 Label notHasException2(env);
63 BRANCH(HasPendingException(glue), &hasException, ¬HasException2);
64 Bind(¬HasException2);
65 Label multilineKey(env);
66 Label notMultilineKey(env);
67 BRANCH(TaggedIsTrue(multilineResult), &multilineKey, ¬MultilineKey);
68 Bind(&multilineKey);
69 {
70 bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_MULTILINE));
71 Jump(¬MultilineKey);
72 }
73 Bind(¬MultilineKey);
74 GateRef dotAllResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::DOT_ALL_INDEX);
75 Label notHasException3(env);
76 BRANCH(HasPendingException(glue), &hasException, ¬HasException3);
77 Bind(¬HasException3);
78 Label dotAllKey(env);
79 Label notDotAllKey(env);
80 BRANCH(TaggedIsTrue(dotAllResult), &dotAllKey, ¬DotAllKey);
81 Bind(&dotAllKey);
82 {
83 bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_DOTALL));
84 Jump(¬DotAllKey);
85 }
86 Bind(¬DotAllKey);
87 GateRef unicodeResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::UNICODE_INDEX);
88 Label notHasException4(env);
89 BRANCH(HasPendingException(glue), &hasException, ¬HasException4);
90 Bind(¬HasException4);
91 Label unicodeKey(env);
92 Label notUnicodeKey(env);
93 BRANCH(TaggedIsTrue(unicodeResult), &unicodeKey, ¬UnicodeKey);
94 Bind(&unicodeKey);
95 {
96 bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_UTF16));
97 Jump(¬UnicodeKey);
98 }
99 Bind(¬UnicodeKey);
100 GateRef stickyResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::STICKY_INDEX);
101 Label notHasException5(env);
102 BRANCH(HasPendingException(glue), &hasException, ¬HasException5);
103 Bind(¬HasException5);
104 Label stickyKey(env);
105 Label notStickyKey(env);
106 BRANCH(TaggedIsTrue(stickyResult), &stickyKey, ¬StickyKey);
107 Bind(&stickyKey);
108 {
109 bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_STICKY));
110 Jump(¬StickyKey);
111 }
112 Bind(¬StickyKey);
113 GateRef indicesResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::HAS_INDICES_INDEX);
114 Label notHasException6(env);
115 BRANCH(HasPendingException(glue), &hasException, ¬HasException6);
116 Bind(¬HasException6);
117 Label hasIndicesKey(env);
118 Label notHasIndicesKey(env);
119 BRANCH(TaggedIsTrue(indicesResult), &hasIndicesKey, ¬HasIndicesKey);
120 Bind(&hasIndicesKey);
121 {
122 bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_HASINDICES));
123 Jump(¬HasIndicesKey);
124 }
125 Bind(¬HasIndicesKey);
126 GateRef flagsStr = CallRuntime(glue, RTSTUB_ID(GetAllFlagsInternal), { IntToTaggedInt(*bitFlagsStr)});
127 result->WriteVariable(flagsStr);
128 Jump(exit);
129 Bind(&hasException);
130 {
131 result->WriteVariable(GetGlobalConstantValue(VariableType::JS_POINTER(),
132 glue, ConstantIndex::EMPTY_STRING_OBJECT_INDEX));
133 Jump(exit);
134 }
135 }
136 }
137
TryToFastGetProperty(GateRef glue,GateRef thisValue,ConstantIndex constIndex)138 GateRef BuiltinsRegExpStubBuilder::TryToFastGetProperty(GateRef glue, GateRef thisValue, ConstantIndex constIndex)
139 {
140 auto env = GetEnvironment();
141 Label entry(env);
142 Label exit(env);
143 env->SubCfgEntry(&entry);
144 DEFVARIABLE(result, VariableType::JS_ANY(), TaggedFalse());
145 GateRef key = GetGlobalConstantValue(VariableType::JS_POINTER(), glue, constIndex);
146 GateRef property = FastGetPropertyByName(glue, thisValue, key, ProfileOperation());
147 Label hasException(env);
148 Label notHasException(env);
149 BRANCH(HasPendingException(glue), &hasException, ¬HasException);
150 Bind(&hasException);
151 {
152 result = Exception();
153 Jump(&exit);
154 }
155 Bind(¬HasException);
156 {
157 result = FastToBoolean(property);
158 Jump(&exit);
159 }
160 Bind(&exit);
161 auto res = *result;
162 env->SubCfgExit();
163 return res;
164 }
165 } // namespace panda::ecmascript::kungfu
166