/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ecmascript/compiler/builtins/builtins_regexp_stub_builder.h" #include "ecmascript/compiler/new_object_stub_builder.h" #include "ecmascript/regexp/regexp_parser.h" namespace panda::ecmascript::kungfu { void BuiltinsRegExpStubBuilder::GetFlags(GateRef glue, GateRef thisValue, [[maybe_unused]] GateRef numArgs, Variable* result, Label* exit, Label *slowPath) { auto env = GetEnvironment(); Label isEcmaObject(env); BRANCH(IsEcmaObject(thisValue), &isEcmaObject, slowPath); Bind(&isEcmaObject); Label fastRegExpPath(env); GateRef fastRegExp = CallNGCRuntime(glue, RTSTUB_ID(IsFastRegExp), {glue, thisValue}); BRANCH(fastRegExp, slowPath, &fastRegExpPath); Bind(&fastRegExpPath); { Label hasException(env); DEFVARIABLE(bitFlagsStr, VariableType::INT32(), Int32(0)); GateRef globalResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::GLOBAL_STRING_INDEX); Label notHasException(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException); Bind(¬HasException); Label globalKey(env); Label notGlobalKey(env); BRANCH(TaggedIsTrue(globalResult), &globalKey, ¬GlobalKey); Bind(&globalKey); { bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_GLOBAL)); Jump(¬GlobalKey); } Bind(¬GlobalKey); GateRef ignoreCaseResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::IGNORE_CASE_INDEX); Label notHasException1(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException1); Bind(¬HasException1); Label ignoreCaseKey(env); Label notIgnoreCaseKey(env); BRANCH(TaggedIsTrue(ignoreCaseResult), &ignoreCaseKey, ¬IgnoreCaseKey); Bind(&ignoreCaseKey); { bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_IGNORECASE)); Jump(¬IgnoreCaseKey); } Bind(¬IgnoreCaseKey); GateRef multilineResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::MULTILINE_INDEX); Label notHasException2(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException2); Bind(¬HasException2); Label multilineKey(env); Label notMultilineKey(env); BRANCH(TaggedIsTrue(multilineResult), &multilineKey, ¬MultilineKey); Bind(&multilineKey); { bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_MULTILINE)); Jump(¬MultilineKey); } Bind(¬MultilineKey); GateRef dotAllResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::DOT_ALL_INDEX); Label notHasException3(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException3); Bind(¬HasException3); Label dotAllKey(env); Label notDotAllKey(env); BRANCH(TaggedIsTrue(dotAllResult), &dotAllKey, ¬DotAllKey); Bind(&dotAllKey); { bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_DOTALL)); Jump(¬DotAllKey); } Bind(¬DotAllKey); GateRef unicodeResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::UNICODE_INDEX); Label notHasException4(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException4); Bind(¬HasException4); Label unicodeKey(env); Label notUnicodeKey(env); BRANCH(TaggedIsTrue(unicodeResult), &unicodeKey, ¬UnicodeKey); Bind(&unicodeKey); { bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_UTF16)); Jump(¬UnicodeKey); } Bind(¬UnicodeKey); GateRef stickyResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::STICKY_INDEX); Label notHasException5(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException5); Bind(¬HasException5); Label stickyKey(env); Label notStickyKey(env); BRANCH(TaggedIsTrue(stickyResult), &stickyKey, ¬StickyKey); Bind(&stickyKey); { bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_STICKY)); Jump(¬StickyKey); } Bind(¬StickyKey); GateRef indicesResult = TryToFastGetProperty(glue, thisValue, ConstantIndex::HAS_INDICES_INDEX); Label notHasException6(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException6); Bind(¬HasException6); Label hasIndicesKey(env); Label notHasIndicesKey(env); BRANCH(TaggedIsTrue(indicesResult), &hasIndicesKey, ¬HasIndicesKey); Bind(&hasIndicesKey); { bitFlagsStr = Int32Or(*bitFlagsStr, Int32(RegExpParser::FLAG_HASINDICES)); Jump(¬HasIndicesKey); } Bind(¬HasIndicesKey); GateRef flagsStr = CallRuntime(glue, RTSTUB_ID(GetAllFlagsInternal), { IntToTaggedInt(*bitFlagsStr)}); result->WriteVariable(flagsStr); Jump(exit); Bind(&hasException); { result->WriteVariable(GetGlobalConstantValue(VariableType::JS_POINTER(), glue, ConstantIndex::EMPTY_STRING_OBJECT_INDEX)); Jump(exit); } } } GateRef BuiltinsRegExpStubBuilder::TryToFastGetProperty(GateRef glue, GateRef thisValue, ConstantIndex constIndex) { auto env = GetEnvironment(); Label entry(env); Label exit(env); env->SubCfgEntry(&entry); DEFVARIABLE(result, VariableType::JS_ANY(), TaggedFalse()); GateRef key = GetGlobalConstantValue(VariableType::JS_POINTER(), glue, constIndex); GateRef property = FastGetPropertyByName(glue, thisValue, key, ProfileOperation()); Label hasException(env); Label notHasException(env); BRANCH(HasPendingException(glue), &hasException, ¬HasException); Bind(&hasException); { result = Exception(); Jump(&exit); } Bind(¬HasException); { result = FastToBoolean(property); Jump(&exit); } Bind(&exit); auto res = *result; env->SubCfgExit(); return res; } } // namespace panda::ecmascript::kungfu