• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 PANDA_PLUGINS_ETS_TYPEAPI_CREATE_H
17 #define PANDA_PLUGINS_ETS_TYPEAPI_CREATE_H
18 
19 #include "assembly-function.h"
20 #include "assembly-program.h"
21 #include "ets_typeapi_create_panda_constants.h"
22 
23 namespace panda {
24 template <typename T>
25 class VMHandle;
26 }  // namespace panda
27 
28 namespace panda::coretypes {
29 class Array;
30 }  // namespace panda::coretypes
31 
32 namespace panda::ets {
33 class EtsCoroutine;
34 class EtsArray;
35 }  // namespace panda::ets
36 
37 namespace panda::ets {
38 class TypeCreatorCtx {
39 public:
Program()40     pandasm::Program &Program()
41     {
42         return prog_;
43     }
44 
45     template <typename T, typename... A>
Alloc(A &&...a)46     T *Alloc(A &&...a)
47     {
48         auto p = std::make_shared<T>(std::forward<A>(a)...);
49         auto ret = p.get();
50         datas_.push_back(std::move(p));
51         return ret;
52     }
53 
54     /**
55      * Adds field with permanent data used in TypeAPI$CtxData$_
56      * also adds intializer into TypeAPI$CtxData$_.cctor that loads that id
57      * from
58      * @param id index of filed in init array
59      * @param type type of that field
60      * @returns field id that can be passed into pandasm instructions to access it
61      */
62     std::string AddInitField(uint32_t id, const pandasm::Type &type);
63 
64     /**
65      * Adds TypeAPI$CtxData$_ to program if it was used
66      * also emplaces necessary cctors
67      */
68     void FlushTypeAPICtxDataRecordsToProgram();
69 
70     /**
71      * Saves objects into current context to provide them to TypeAPI$CtxData$_.cctor
72      * @param objects must live until end of call to `InitializeCtxDataRecord` and may be changed inside this function
73      */
74     void SaveObjects(EtsCoroutine *coro, VMHandle<EtsArray> &objects);
75 
76     EtsArray *GetObjects(EtsCoroutine *coro);
77 
78     /// Initializes TypeAPI$CtxData$_
79     void InitializeCtxDataRecord(EtsCoroutine *coro);
80 
81     /**
82      * Creates TypeAPI$CtxData record if it wasn't created before
83      * @returns TypeAPI$CtxData record
84      */
85     pandasm::Record &GetTypeAPICtxDataRecord();
86 
87     pandasm::Record &AddRefTypeAsExternal(const std::string &name);
88 
89     std::string GetRefVoidInstanceName();
90 
91     /**
92      * Lazily declares primitive reference wrapper
93      * @returns pair of constructor and unwrapper
94      */
95     const std::pair<std::string, std::string> &DeclarePrimitive(const std::string &primTypeName);
96 
AddError(std::string_view err)97     void AddError(std::string_view err)
98     {
99         error_ += err;
100     }
101 
GetError()102     std::optional<std::string_view> GetError() const
103     {
104         if (error_.empty()) {
105             return std::nullopt;
106         }
107         return error_;
108     }
109 
110 private:
111     pandasm::Program prog_;
112     pandasm::Record ctxDataRecord_ {"", panda_file::SourceLang::ETS};
113     std::string ctxDataRecordName_ {};
114     pandasm::Function ctxDataRecordCctor_ {"", panda_file::SourceLang::ETS};
115     std::map<std::string, std::pair<std::string, std::string>> primitiveTypesCtorDtor_;
116     std::vector<std::shared_ptr<void>> datas_;
117     std::string error_;
118 
119     coretypes::Array *initArrObject_ {};
120 };
121 
122 enum class TypeCreatorKind {
123     CLASS,
124     INTERFACE,
125     LAMBDA_TYPE,
126 };
127 
128 class TypeCreator {
129 public:
130     virtual TypeCreatorKind GetKind() const = 0;
131     virtual pandasm::Type GetType() const = 0;
132 
TypeCreator(TypeCreatorCtx * ctx)133     explicit TypeCreator(TypeCreatorCtx *ctx) : ctx_(ctx) {}
134 
GetCtx()135     TypeCreatorCtx *GetCtx() const
136     {
137         return ctx_;
138     }
139 
140 private:
141     TypeCreatorCtx *ctx_;
142 };
143 
144 class ClassCreator final : public TypeCreator {
145 public:
ClassCreator(pandasm::Record * rec,TypeCreatorCtx * ctx)146     explicit ClassCreator(pandasm::Record *rec, TypeCreatorCtx *ctx) : TypeCreator(ctx), rec_(rec) {}
147 
GetKind()148     TypeCreatorKind GetKind() const override
149     {
150         return TypeCreatorKind::CLASS;
151     }
152 
GetType()153     pandasm::Type GetType() const override
154     {
155         return pandasm::Type {rec_->name, 0, true};
156     }
157 
GetRec()158     pandasm::Record *GetRec() const
159     {
160         return rec_;
161     }
162 
163 private:
164     pandasm::Record *rec_;
165 };
166 
167 class InterfaceCreator final : public TypeCreator {
168 public:
InterfaceCreator(pandasm::Record * rec,TypeCreatorCtx * ctx)169     explicit InterfaceCreator(pandasm::Record *rec, TypeCreatorCtx *ctx) : TypeCreator(ctx), rec_(rec) {}
170 
GetKind()171     TypeCreatorKind GetKind() const override
172     {
173         return TypeCreatorKind::INTERFACE;
174     }
175 
GetType()176     pandasm::Type GetType() const override
177     {
178         return pandasm::Type {rec_->name, 0, true};
179     }
180 
GetRec()181     pandasm::Record *GetRec() const
182     {
183         return rec_;
184     }
185 
186 private:
187     pandasm::Record *rec_;
188 };
189 
190 class LambdaTypeCreator final : public TypeCreator {
191 public:
LambdaTypeCreator(TypeCreatorCtx * ctx)192     explicit LambdaTypeCreator(TypeCreatorCtx *ctx) : TypeCreator(ctx)
193     {
194         for (const auto &attr : typeapi_create_consts::ATTR_INTERFACE) {
195             rec_.metadata->SetAttribute(attr);
196         }
197         rec_.metadata->SetAttributeValue(typeapi_create_consts::ATTR_ACCESS,
198                                          typeapi_create_consts::ATTR_ACCESS_VAL_PUBLIC);
199     }
200 
GetKind()201     TypeCreatorKind GetKind() const override
202     {
203         return TypeCreatorKind::LAMBDA_TYPE;
204     }
205 
GetType()206     pandasm::Type GetType() const override
207     {
208         ASSERT(finished_);
209         return pandasm::Type {name_, 0};
210     }
211 
GetFunctionName()212     const std::string &GetFunctionName() const
213     {
214         ASSERT(finished_);
215         return fnName_;
216     }
217 
218     void AddParameter(pandasm::Type param);
219 
220     void AddResult(const pandasm::Type &type);
221 
222     void Create();
223 
224 private:
225     std::string name_ = "FunctionalInterface";
226     std::string fnName_ = "invoke";
227     pandasm::Record rec_ {name_, SourceLanguage::ETS};
228     pandasm::Function fn_ {fnName_, SourceLanguage::ETS};
229     bool finished_ = false;
230 };
231 
232 class PandasmMethodCreator {
233 public:
PandasmMethodCreator(std::string name,TypeCreatorCtx * ctx)234     PandasmMethodCreator(std::string name, TypeCreatorCtx *ctx)
235         : ctx_(ctx), name_(name), fn_(std::move(name), SourceLanguage::ETS)
236     {
237     }
238 
239     void AddParameter(pandasm::Type param);
240 
241     void AddResult(pandasm::Type type);
242 
243     void Create();
244 
GetFunctionName()245     const std::string &GetFunctionName() const
246     {
247         ASSERT(finished_);
248         return name_;
249     }
250 
GetFn()251     pandasm::Function &GetFn()
252     {
253         ASSERT(!finished_);
254         return fn_;
255     }
256 
Ctx()257     TypeCreatorCtx *Ctx() const
258     {
259         return ctx_;
260     }
261 
262 private:
263     TypeCreatorCtx *ctx_;
264     std::string name_;
265     pandasm::Function fn_;
266     bool finished_ = false;
267 };
268 
269 }  // namespace panda::ets
270 
271 #endif  // PANDA_PLUGINS_ETS_TYPEAPI_CREATE_H
272