1/*
2 * Copyright (c) 2022 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_NEW_OBJECT_STUB_BUILDER_H
17#define ECMASCRIPT_COMPILER_NEW_OBJECT_STUB_BUILDER_H
18
19#include "ecmascript/compiler/builtins/builtins_string_stub_builder.h"
20#include "ecmascript/compiler/profiler_operation.h"
21#include "ecmascript/compiler/stub_builder.h"
22
23namespace panda::ecmascript::kungfu {
24
25struct TraceIdInfo {
26    GateRef pc = 0;
27    GateRef traceId = 0;
28    bool isPc = true;
29};
30
31class NewObjectStubBuilder : public StubBuilder {
32public:
33    explicit NewObjectStubBuilder(StubBuilder *parent)
34        : StubBuilder(parent) {}
35    explicit NewObjectStubBuilder(Environment *env)
36        : StubBuilder(env) {}
37    ~NewObjectStubBuilder() override = default;
38    NO_MOVE_SEMANTIC(NewObjectStubBuilder);
39    NO_COPY_SEMANTIC(NewObjectStubBuilder);
40    void GenerateCircuit() override {}
41
42    void SetParameters(GateRef glue, GateRef size)
43    {
44        glue_ = glue;
45        size_ = size;
46    }
47
48    void SetGlue(GateRef glue)
49    {
50        glue_ = glue;
51    }
52
53    void NewLexicalEnv(Variable *result, Label *exit, GateRef numSlots, GateRef parent);
54    void NewJSObject(Variable *result, Label *exit, GateRef hclass, GateRef size);
55    void NewJSObject(Variable *result, Label *exit, GateRef hclass);
56    void NewSObject(Variable *result, Label *exit, GateRef hclass);
57    GateRef NewJSObject(GateRef glue, GateRef hclass);
58    GateRef NewSObject(GateRef glue, GateRef hclass);
59    GateRef NewJSFunctionByHClass(GateRef glue, GateRef method, GateRef hclass,
60                                  FunctionKind targetKind = FunctionKind::LAST_FUNCTION_KIND);
61    GateRef NewSFunctionByHClass(GateRef glue, GateRef method, GateRef hclass,
62                                 FunctionKind targetKind = FunctionKind::LAST_FUNCTION_KIND);
63    GateRef CloneJSFunction(GateRef glue, GateRef value);
64    GateRef CloneProperties(GateRef glue, GateRef currentEnv, GateRef elements, GateRef obj);
65    GateRef NewAccessorData(GateRef glue);
66    GateRef CloneObjectLiteral(GateRef glue, GateRef literal, GateRef currentEnv);
67    GateRef CreateObjectHavingMethod(GateRef glue, GateRef literal, GateRef currentEnv);
68    GateRef NewJSProxy(GateRef glue, GateRef target, GateRef handler);
69    GateRef NewJSArray(GateRef glue, GateRef hclass);
70    GateRef NewTaggedArray(GateRef glue, GateRef len);
71    GateRef NewMutantTaggedArray(GateRef glue, GateRef len);
72    GateRef CopyArray(GateRef glue, GateRef elements, GateRef oldLen, GateRef newLen,
73                      RegionSpaceFlag spaceType = RegionSpaceFlag::IN_YOUNG_SPACE);
74    GateRef ExtendArrayCheck(GateRef glue, GateRef elements, GateRef newLen,
75                        RegionSpaceFlag spaceType = RegionSpaceFlag::IN_YOUNG_SPACE);
76    void ExtendArray(Variable *result, GateRef glue, GateRef elements, GateRef newLen, Label *exit,
77                           RegionSpaceFlag spaceType = RegionSpaceFlag::IN_YOUNG_SPACE, bool isMutantArray = false);
78    void ExtendMutantArray(Variable *result, GateRef glue, GateRef elements, GateRef newLen, Label *exit,
79                           RegionSpaceFlag spaceType = RegionSpaceFlag::IN_YOUNG_SPACE);
80    GateRef NewJSArrayWithSize(GateRef hclass, GateRef size);
81    GateRef NewJSForinIterator(GateRef glue, GateRef receiver, GateRef keys, GateRef cachedHclass);
82    GateRef LoadHClassFromMethod(GateRef glue, GateRef method);
83    GateRef LoadSHClassFromMethod(GateRef glue, GateRef method);
84    GateRef NewJSFunction(GateRef glue, GateRef method,
85                          FunctionKind targetKind = FunctionKind::LAST_FUNCTION_KIND);
86    GateRef NewJSSendableFunction(GateRef glue, GateRef method,
87                                  FunctionKind targetKind = FunctionKind::LAST_FUNCTION_KIND);
88    void NewJSFunction(GateRef glue, GateRef jsFunc, GateRef index, GateRef length, GateRef lexEnv,
89                       Variable *result, Label *success, Label *failed, GateRef slotId,
90                       FunctionKind targetKind = FunctionKind::LAST_FUNCTION_KIND);
91    void SetProfileTypeInfoCellToFunction(GateRef jsFunc, GateRef definedFunc, GateRef slotId);
92    GateRef NewJSBoundFunction(GateRef glue, GateRef target, GateRef boundThis, GateRef args);
93    GateRef EnumerateObjectProperties(GateRef glue, GateRef obj);
94    void NewArgumentsList(Variable *result, Label *exit, GateRef sp, GateRef startIdx, GateRef numArgs);
95    void FillArgumentsList(GateRef argumentsList, GateRef sp, GateRef startIdx, GateRef numArgs);
96    GateRef NewArgumentsListObj(GateRef numArgs);
97    void NewArgumentsObj(Variable *result, Label *exit, GateRef argumentsList, GateRef numArgs);
98    void AssignRestArg(Variable *result, Label *exit, GateRef sp, GateRef startIdx, GateRef numArgs,
99                       GateRef intialHClass);
100    void AllocLineStringObject(Variable *result, Label *exit, GateRef length, bool compressed);
101    void AllocSlicedStringObject(Variable *result, Label *exit, GateRef from, GateRef length,
102        FlatStringStubBuilder *flatString);
103    void AllocTreeStringObject(Variable *result, Label *exit, GateRef first, GateRef second,
104        GateRef length, bool compressed);
105    void HeapAlloc(Variable *result, Label *exit, RegionSpaceFlag spaceType, GateRef hclass);
106    void NewJSArrayLiteral(Variable *result, Label *exit, RegionSpaceFlag spaceType, GateRef obj, GateRef hclass,
107                           GateRef trackInfo, bool isEmptyArray);
108    GateRef NewTrackInfo(GateRef glue, GateRef cachedHClass, GateRef cachedFunc, RegionSpaceFlag spaceFlag,
109                         GateRef arraySize);
110    // Note: The size is the num of bytes, it is required to be divisible by 8.
111    void InitializeWithSpeicalValue(Label *exit, GateRef object, GateRef value, GateRef start, GateRef end,
112                                    MemoryAttribute mAttr = MemoryAttribute::Default());
113    GateRef FastNewThisObject(GateRef glue, GateRef ctor);
114    GateRef FastSuperAllocateThis(GateRef glue, GateRef superCtor, GateRef newTarget);
115    GateRef NewThisObjectChecked(GateRef glue, GateRef ctor);
116    GateRef CreateEmptyObject(GateRef glue);
117    GateRef CreateEmptyArray(GateRef glue);
118    GateRef CreateEmptyArray(GateRef glue, GateRef jsFunc, TraceIdInfo traceIdInfo,
119        GateRef profileTypeInfo, GateRef slotId, ProfileOperation callback);
120    GateRef CreateArrayWithBuffer(GateRef glue, GateRef index, GateRef jsFunc, TraceIdInfo traceIdInfo,
121                                  GateRef profileTypeInfo, GateRef slotId, ProfileOperation callback);
122    void NewTaggedArrayChecked(Variable *result, GateRef len, Label *exit);
123    void NewMutantTaggedArrayChecked(Variable *result, GateRef len, Label *exit);
124    template <typename IteratorType, typename CollectionType>
125    void CreateJSCollectionIterator(Variable *result, Label *exit, GateRef set, GateRef kind);
126    void CreateJSTypedArrayIterator(Variable *result, Label *exit, GateRef set, GateRef kind);
127    GateRef NewTaggedSubArray(GateRef glue, GateRef srcTypedArray, GateRef elementSize, GateRef newLength,
128        GateRef beginIndex, GateRef arrayCls, GateRef buffer);
129    GateRef NewTypedArray(GateRef glue, GateRef srcTypedArray, GateRef srcType, GateRef length);
130    GateRef NewJSObjectByConstructor(GateRef glue, GateRef constructor, GateRef newTarget);
131    GateRef NewFloat32ArrayObj(GateRef glue, GateRef glueGlobalEnv);
132    GateRef NewFloat32ArrayWithSize(GateRef glue, GateRef size);
133    GateRef NewTypedArrayFromCtor(GateRef glue, GateRef ctor, GateRef length, Label *slowPath);
134    void NewByteArray(Variable *result, Label *exit, GateRef elementSize, GateRef length);
135    GateRef NewProfileTypeInfoCell(GateRef glue, GateRef value);
136    GateRef GetElementSizeFromType(GateRef glue, GateRef type);
137    GateRef GetOnHeapHClassFromType(GateRef glue, GateRef type);
138private:
139    static constexpr int MAX_TAGGED_ARRAY_LENGTH = 50;
140    GateRef LoadTrackInfo(GateRef glue, GateRef jsFunc, TraceIdInfo traceIdInfo,
141        GateRef profileTypeInfo, GateRef slotId, GateRef slotValue, GateRef arrayLiteral, ProfileOperation callback);
142    GateRef LoadArrayHClassSlowPath(
143        GateRef glue, GateRef jsFunc, TraceIdInfo traceIdInfo, GateRef arrayLiteral, ProfileOperation callback);
144    GateRef CreateEmptyArrayCommon(GateRef glue, GateRef hclass, GateRef trackInfo);
145    void AllocateInYoungPrologue(Variable *result, Label *callRuntime, Label *exit);
146    void AllocateInYoung(Variable *result, Label *exit, GateRef hclass);
147    void AllocateInYoung(Variable *result, Label *error, Label *noError, GateRef hclass);
148    void AllocateInSOldPrologue(Variable *result, Label *callRuntime, Label *exit);
149    void AllocateInSOld(Variable *result, Label *exit, GateRef hclass);
150    void InitializeTaggedArrayWithSpeicalValue(Label *exit,
151        GateRef array, GateRef value, GateRef start, GateRef length);
152    GateRef glue_ {Circuit::NullGate()};
153    GateRef size_ {0};
154};
155}  // namespace panda::ecmascript::kungfu
156#endif  // ECMASCRIPT_COMPILER_NEW_OBJECT_STUB_BUILDER_H
157