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_ASSEMBLER_MODULE_H
17#define ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_H
18
19#include <string>
20#include <vector>
21
22#include "ecmascript/compiler/assembler/assembler.h"
23#include "ecmascript/compiler/call_signature.h"
24#include "ecmascript/compiler/rt_call_signature.h"
25#include "ecmascript/frames.h"
26#include "ecmascript/stubs/runtime_stub_list.h"
27
28namespace panda::ecmascript::kungfu {
29class CompilationConfig;
30class AssemblerModule {
31public:
32    AssemblerModule() = default;
33    ~AssemblerModule()
34    {
35        for (auto it : symbolTable_) {
36            delete it.second;
37        }
38    }
39
40    void Run(const CompilationConfig *cfg, Chunk* chunk);
41
42    size_t GetFunctionCount() const
43    {
44        return symbolTable_.size();
45    }
46
47    size_t GetFunction(int id) const
48    {
49        panda::ecmascript::Label *label = GetFunctionLabel(id);
50        if (label->IsBound()) {
51            return label->GetPos();
52        } else {
53            LOG_ECMA(FATAL) << "this branch is unreachable";
54            UNREACHABLE();
55        }
56    }
57
58    panda::ecmascript::Label* GetFunctionLabel(int id) const
59    {
60        return symbolTable_.at(id);
61    }
62
63    uint8_t* GetBuffer() const
64    {
65        return buffer_;
66    }
67
68    size_t GetBufferSize() const
69    {
70        return bufferSize_;
71    }
72
73    void SetUpForAsmStubs();
74
75    const std::vector<const CallSignature*> &GetCSigns() const
76    {
77        return asmCallSigns_;
78    }
79
80    const CallSignature *GetCSign(size_t i) const
81    {
82        return asmCallSigns_[i];
83    }
84
85    const std::vector<size_t> &GetStubsOffset() const
86    {
87        return stubsOffset_;
88    }
89
90    void GenerateStubsX64(Chunk* chunk);
91    void GenerateStubsAarch64(Chunk* chunk);
92
93    static bool IsCallNew(JSCallMode mode);
94    static int GetArgcFromJSCallMode(JSCallMode mode);
95    static bool JSModeHaveThisArg(JSCallMode mode);
96    static bool JSModeHaveNewTargetArg(JSCallMode mode);
97    static bool IsJumpToCallCommonEntry(JSCallMode mode);
98private:
99    std::vector<const CallSignature *> asmCallSigns_;
100    std::map<int, panda::ecmascript::Label *> symbolTable_;
101    std::vector<size_t> stubsOffset_;
102    uint8_t* buffer_ {nullptr};
103    size_t bufferSize_ {0};
104};
105
106class AssemblerStub {
107public:
108    virtual void GenerateX64(Assembler* assembler) = 0;
109    virtual void GenerateAarch64(Assembler* assembler) = 0;
110    virtual ~AssemblerStub() = default;
111};
112
113#define DECLARE_ASM_STUB_CLASS(name)                        \
114class name##Stub : public AssemblerStub {                   \
115public:                                                     \
116    ~name##Stub() = default;                                \
117    void GenerateX64(Assembler* assembler) override;        \
118    void GenerateAarch64(Assembler* assembler) override;    \
119};
120RUNTIME_ASM_STUB_LIST(DECLARE_ASM_STUB_CLASS)
121#undef DECLARE_ASM_STUB_CLASS
122}  // namespace panda::ecmascript::kunfu
123#endif  // ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_H
124