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" 19namespace panda::ecmascript::kungfu { 20 21void 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 138GateRef 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