1/*
2 * Copyright (c) 2022-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#ifndef ECMASCRIPT_COMPILER_BUILTINS_STRING_STUB_BUILDER_H
17#define ECMASCRIPT_COMPILER_BUILTINS_STRING_STUB_BUILDER_H
18#include "ecmascript/compiler/stub_builder-inl.h"
19#include "ecmascript/compiler/builtins/builtins_stubs.h"
20
21namespace panda::ecmascript::kungfu {
22class FlatStringStubBuilder;
23struct StringInfoGateRef;
24
25class BuiltinsStringStubBuilder : public BuiltinsStubBuilder {
26public:
27    explicit BuiltinsStringStubBuilder(StubBuilder *parent)
28        : BuiltinsStubBuilder(parent) {}
29    BuiltinsStringStubBuilder(CallSignature *callSignature, Environment *env)
30        : BuiltinsStubBuilder(callSignature, env) {}
31    explicit BuiltinsStringStubBuilder(Environment* env): BuiltinsStubBuilder(env) {}
32    ~BuiltinsStringStubBuilder() override = default;
33    NO_MOVE_SEMANTIC(BuiltinsStringStubBuilder);
34    NO_COPY_SEMANTIC(BuiltinsStringStubBuilder);
35    void GenerateCircuit() override {}
36
37#define DECLARE_BUILTINS_SRRING_STUB_BUILDER(method, ...)           \
38    void method(GateRef glue, GateRef thisValue, GateRef numArgs, Variable* res, Label *exit, Label *slowPath);
39BUILTINS_WITH_STRING_STUB_BUILDER(DECLARE_BUILTINS_SRRING_STUB_BUILDER)
40#undef DECLARE_BUILTINS_SRRING_STUB_BUILDER
41
42    void LocaleCompare(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *res, Label *exit, Label *slowPath);
43    void StringIteratorNext(GateRef glue, GateRef thisValue, GateRef numArgs,
44                            Variable *res, Label *exit, Label *slowPath);
45
46    GateRef ConvertAndClampRelativeIndex(GateRef index, GateRef length);
47    GateRef StringAt(const StringInfoGateRef &stringInfoGate, GateRef index);
48    GateRef FastSubString(GateRef glue, GateRef thisValue, GateRef from, GateRef len,
49        const StringInfoGateRef &stringInfoGate);
50    GateRef FastSubUtf8String(GateRef glue, GateRef from, GateRef len, const StringInfoGateRef &stringInfoGate);
51    GateRef FastSubUtf16String(GateRef glue, GateRef from, GateRef len, const StringInfoGateRef &stringInfoGate);
52    GateRef FastStringCharCodeAt(GateRef glue, GateRef thisValue, GateRef pos);
53    GateRef GetSubstitution(GateRef glue, GateRef searchString, GateRef thisString,
54        GateRef pos, GateRef replaceString);
55    void CopyChars(GateRef glue, GateRef dst, GateRef source, GateRef sourceLength, GateRef size, VariableType type);
56    void CopyUtf16AsUtf8(GateRef glue, GateRef dst, GateRef src, GateRef sourceLength);
57    void CopyUtf8AsUtf16(GateRef glue, GateRef dst, GateRef src, GateRef sourceLength);
58    GateRef StringIndexOf(GateRef lhsData, bool lhsIsUtf8, GateRef rhsData, bool rhsIsUtf8,
59                          GateRef pos, GateRef max, GateRef rhsCount);
60    GateRef StringIndexOf(const StringInfoGateRef &lStringInfoGate,
61        const StringInfoGateRef &rStringInfoGate, GateRef pos);
62    GateRef GetSingleCharCodeByIndex(GateRef str, GateRef index);
63    GateRef CreateStringBySingleCharCode(GateRef glue, GateRef charCode);
64    GateRef CreateFromEcmaString(GateRef glue, GateRef index, const StringInfoGateRef &stringInfoGate);
65    GateRef StringConcat(GateRef glue, GateRef leftString, GateRef rightString);
66    GateRef EcmaStringTrim(GateRef glue, GateRef srcString, GateRef trimMode);
67    GateRef EcmaStringTrimBody(GateRef glue, GateRef thisValue, StringInfoGateRef srcStringInfoGate,
68        GateRef trimMode, GateRef isUtf8);
69    void StoreParent(GateRef glue, GateRef object, GateRef parent);
70    void StoreStartIndex(GateRef glue, GateRef object, GateRef startIndex);
71    void StoreHasBackingStore(GateRef glue, GateRef object, GateRef hasBackingStore);
72    GateRef IsSubStringAt(GateRef lhsData, bool lhsIsUtf8, GateRef rhsData, bool rhsIsUtf8,
73        GateRef pos, GateRef rhsCount);
74    GateRef IsSubStringAt(const StringInfoGateRef &lStringInfoGate,
75        const StringInfoGateRef &rStringInfoGate, GateRef pos);
76    GateRef GetSubString(GateRef glue, GateRef thisValue, GateRef from, GateRef len);
77    GateRef GetFastSubString(GateRef glue, GateRef thisValue, GateRef start, GateRef len);
78private:
79    GateRef ChangeStringTaggedPointerToInt64(GateRef x)
80    {
81        return GetEnvironment()->GetBuilder()->ChangeTaggedPointerToInt64(x);
82    }
83    GateRef GetStringDataFromLineOrConstantString(GateRef str);
84    GateRef CanBeCompressed(GateRef utf16Data, GateRef utf16Len, bool isUtf16);
85    GateRef GetUtf16Data(GateRef stringData, GateRef index);
86    GateRef IsASCIICharacter(GateRef data);
87    GateRef GetUtf8Data(GateRef stringData, GateRef index);
88    GateRef GetSingleCharCodeFromConstantString(GateRef str, GateRef index);
89    GateRef GetSingleCharCodeFromLineString(GateRef str, GateRef index);
90    GateRef GetSingleCharCodeFromSlicedString(GateRef str, GateRef index);
91    void CheckParamsAndGetPosition(GateRef glue, GateRef thisValue, GateRef numArgs,
92        Variable* pos, Label *exit, Label *slowPath, Label *posIsValid);
93};
94
95class FlatStringStubBuilder : public StubBuilder {
96public:
97    explicit FlatStringStubBuilder(StubBuilder *parent)
98        : StubBuilder(parent) {}
99    ~FlatStringStubBuilder() override = default;
100    NO_MOVE_SEMANTIC(FlatStringStubBuilder);
101    NO_COPY_SEMANTIC(FlatStringStubBuilder);
102    void GenerateCircuit() override {}
103
104    void FlattenString(GateRef glue, GateRef str, Label *fastPath);
105    void FlattenStringWithIndex(GateRef glue, GateRef str, Variable *index, Label *fastPath);
106    GateRef GetParentFromSlicedString(GateRef string)
107    {
108        GateRef offset = IntPtr(SlicedString::PARENT_OFFSET);
109        return Load(VariableType::JS_POINTER(), string, offset);
110    }
111    GateRef GetStartIndexFromSlicedString(GateRef string)
112    {
113        GateRef offset = IntPtr(SlicedString::STARTINDEX_OFFSET);
114        return Load(VariableType::INT32(), string, offset);
115    }
116    GateRef GetHasBackingStoreFromSlicedString(GateRef string)
117    {
118        GateRef offset = IntPtr(SlicedString::BACKING_STORE_FLAG);
119        return Load(VariableType::INT32(), string, offset);
120    }
121
122    GateRef GetFlatString()
123    {
124        return flatString_.ReadVariable();
125    }
126
127    GateRef GetStartIndex()
128    {
129        return startIndex_.ReadVariable();
130    }
131
132    GateRef GetLength()
133    {
134        return length_;
135    }
136
137private:
138    Variable flatString_ { GetEnvironment(), VariableType::JS_POINTER(), NextVariableId(), Undefined() };
139    Variable startIndex_ { GetEnvironment(), VariableType::INT32(), NextVariableId(), Int32(0) };
140    GateRef length_ { Circuit::NullGate() };
141};
142
143struct StringInfoGateRef {
144    GateRef string_ { Circuit::NullGate() };
145    GateRef startIndex_ { Circuit::NullGate() };
146    GateRef length_ { Circuit::NullGate() };
147    StringInfoGateRef(FlatStringStubBuilder *flatString) : string_(flatString->GetFlatString()),
148                                                           startIndex_(flatString->GetStartIndex()),
149                                                           length_(flatString->GetLength()) {}
150    GateRef GetString() const
151    {
152        return string_;
153    }
154
155    GateRef GetStartIndex() const
156    {
157        return startIndex_;
158    }
159
160    GateRef GetLength() const
161    {
162        return length_;
163    }
164};
165}  // namespace panda::ecmascript::kungfu
166#endif  // ECMASCRIPT_COMPILER_BUILTINS_STRING_STUB_BUILDER_H