• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #include <common.h>
17 #include <utility>
18 
19 using std::string, std::cout, std::endl, std::vector;
20 
21 static es2panda_Impl *impl = nullptr;
22 
23 static thread_local StageArena currentArena;
24 
instance()25 StageArena* StageArena::instance()
26 {
27     return &currentArena;
28 }
29 
add(void * pointer)30 void StageArena::add(void* pointer)
31 {
32     if (pointer)
33         allocated.push_back(pointer);
34 }
35 
cleanup()36 void StageArena::cleanup()
37 {
38     if (totalSize > 0 && false)
39         printf("cleanup %d objects %d bytes\n", (int)allocated.size(), (int)totalSize);
40     for (auto it : allocated) {
41         free(it);
42     }
43     totalSize = 0;
44     allocated.clear();
45 }
46 
StageArena()47 StageArena::StageArena()
48 {
49     totalSize = 0;
50 }
51 
~StageArena()52 StageArena::~StageArena()
53 {
54     cleanup();
55 }
56 
strdup(const char * string)57 char* StageArena::strdup(const char* string)
58 {
59     auto* arena = StageArena::instance();
60     auto size = strlen(string) + 1;
61     char* memory = (char*)arena->alloc(size);
62     memcpy(memory, string, size);
63     return memory;
64 }
65 
alloc(size_t size)66 void* StageArena::alloc(size_t size)
67 {
68     void* result = malloc(size);
69     totalSize += size;
70     add(result);
71     return result;
72 }
73 
74 #ifdef KOALA_WINDOWS
75     #include <windows.h>
76     #define PLUGIN_DIR "windows_host_tools"
77     #define LIB_PREFIX ""
78     #define LIB_SUFFIX ".dll"
79 #endif
80 
81 #ifdef KOALA_LINUX
82     #include <dlfcn.h>
83 
84     #ifdef __x86_64__
85         #define PLUGIN_DIR "linux_host_tools"
86     #else
87         #define PLUGIN_DIR "linux_arm64_host_tools"
88     #endif
89 
90     #define LIB_PREFIX "lib"
91     #define LIB_SUFFIX ".so"
92 #endif
93 
94 const char* DEFAULT_SDK_PATH = "../../../incremental/tools/panda/node_modules/@panda/sdk" ;
95 const char* NAME = LIB_PREFIX "es2panda-public" LIB_SUFFIX;
96 
FindLibrary()97 void* FindLibrary()
98 {
99     char* envValue = getenv("PANDA_SDK_PATH");
100     if (!envValue) {
101         std::cout << "PANDA_SDK_PATH not specified, assuming " << DEFAULT_SDK_PATH << std::endl;
102     }
103     std::string prefix = envValue ? std::string(envValue) : DEFAULT_SDK_PATH;
104     std::string libraryName = prefix + ("/" PLUGIN_DIR "/lib/") + NAME;
105     return loadLibrary(libraryName);
106 }
107 
GetImpl()108 es2panda_Impl *GetImpl()
109 {
110     if (impl) {
111         return impl;
112     }
113     auto library = FindLibrary();
114     if (!library) {
115         printf("No library (es2panda_lib.cc)");
116         abort();
117     }
118     auto symbol = findSymbol(library, "es2panda_GetImpl");
119     if (!symbol) {
120         printf("no entry point");
121         abort();
122     }
123     impl = reinterpret_cast<es2panda_Impl *(*)(int)>(symbol)(ES2PANDA_LIB_VERSION);
124     return impl;
125 }
126 
intToState(KInt state)127 es2panda_ContextState intToState(KInt state)
128 {
129     return es2panda_ContextState(state);
130 }
131 
getString(KStringPtr ptr)132 string getString(KStringPtr ptr)
133 {
134     return ptr.data();
135 }
136 
getStringCopy(KStringPtr & ptr)137 char* getStringCopy(KStringPtr& ptr)
138 {
139     return StageArena::strdup(ptr.c_str() ? ptr.c_str() : "");
140 }
141 
unpackUInt(const KByte * bytes)142 inline KUInt unpackUInt(const KByte* bytes)
143 {
144     const KUInt BYTE_0 = 0;
145     const KUInt BYTE_1 = 1;
146     const KUInt BYTE_2 = 2;
147     const KUInt BYTE_3 = 3;
148 
149     const KUInt BYTE_1_SHIFT = 8;
150     const KUInt BYTE_2_SHIFT = 16;
151     const KUInt BYTE_3_SHIFT = 24;
152     return (
153         bytes[BYTE_0]
154         | (bytes[BYTE_1] << BYTE_1_SHIFT)
155         | (bytes[BYTE_2] << BYTE_2_SHIFT)
156         | (bytes[BYTE_3] << BYTE_3_SHIFT)
157     );
158 }
159 
impl_CreateConfig(KInt argc,KStringArray argvPtr)160 KNativePointer impl_CreateConfig(KInt argc, KStringArray argvPtr) {
161     const std::size_t headerLen = 4;
162 
163     const char** argv = StageArena::allocArray<const char*>(argc);
164     std::size_t position = headerLen;
165     std::size_t strLen;
166     for (std::size_t i = 0; i < static_cast<std::size_t>(argc); ++i) {
167         strLen = unpackUInt(argvPtr + position);
168         position += headerLen;
169         argv[i] = StageArena::strdup(std::string(reinterpret_cast<const char*>(argvPtr + position), strLen).c_str());
170         position += strLen;
171     }
172     return GetImpl()->CreateConfig(argc, argv);
173 }
KOALA_INTEROP_2(CreateConfig,KNativePointer,KInt,KStringArray)174 KOALA_INTEROP_2(CreateConfig, KNativePointer, KInt, KStringArray)
175 
176 KNativePointer impl_DestroyConfig(KNativePointer configPtr) {
177     auto config = reinterpret_cast<es2panda_Config*>(configPtr);
178     GetImpl()->DestroyConfig(config);
179     return nullptr;
180 }
KOALA_INTEROP_1(DestroyConfig,KNativePointer,KNativePointer)181 KOALA_INTEROP_1(DestroyConfig, KNativePointer, KNativePointer)
182 
183 KNativePointer impl_DestroyContext(KNativePointer contextPtr) {
184     auto context = reinterpret_cast<es2panda_Context*>(contextPtr);
185     GetImpl()->DestroyContext(context);
186     StageArena::instance()->cleanup();
187     return nullptr;
188 }
KOALA_INTEROP_1(DestroyContext,KNativePointer,KNativePointer)189 KOALA_INTEROP_1(DestroyContext, KNativePointer, KNativePointer)
190 
191 KNativePointer impl_UpdateCallExpression(
192     KNativePointer contextPtr,
193     KNativePointer nodePtr,
194     KNativePointer calleePtr,
195     KNativePointerArray argumentsPtr,
196     KInt argumentsLen,
197     KNativePointer typeParamsPtr,
198     KBoolean optionalT,
199     KBoolean trailingCommaT
200 ) {
201     auto node = reinterpret_cast<es2panda_AstNode*>(nodePtr);
202     auto context = reinterpret_cast<es2panda_Context*>(contextPtr);
203     auto callee = reinterpret_cast<es2panda_AstNode*>(calleePtr);
204     auto arguments = reinterpret_cast<es2panda_AstNode**>(argumentsPtr);
205     auto typeParams = reinterpret_cast<es2panda_AstNode*>(typeParamsPtr);
206     auto optional = static_cast<bool>(optionalT);
207     auto trailingComma = static_cast<bool>(trailingCommaT);
208 
209     auto nn = GetImpl()->CreateCallExpression(
210         context, callee, arguments, argumentsLen, typeParams, optional, trailingComma
211     );
212     GetImpl()->AstNodeSetOriginalNode(context, nn, node);
213     return nn;
214 }
KOALA_INTEROP_8(UpdateCallExpression,KNativePointer,KNativePointer,KNativePointer,KNativePointer,KNativePointerArray,KInt,KNativePointer,KBoolean,KBoolean)215 KOALA_INTEROP_8(UpdateCallExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt, KNativePointer, KBoolean, KBoolean)
216 
217 KInt impl_IdentifierIdentifierFlags(KNativePointer contextPtr, KNativePointer nodePtr) {
218     auto context = reinterpret_cast<es2panda_Context*>(contextPtr);
219     auto node = reinterpret_cast<es2panda_AstNode*>(nodePtr);
220 
221     return
222         (GetImpl()->IdentifierIsOptionalConst(context, node) ? (1 << 0) : 0) |
223         (GetImpl()->IdentifierIsReferenceConst(context, node) ? (1 << 1) : 0) |
224         (GetImpl()->IdentifierIsTdzConst(context, node) ? (1 << 2) : 0);
225 }
226 KOALA_INTEROP_2(IdentifierIdentifierFlags, KInt, KNativePointer, KNativePointer)
227 
228 /*
229 TODO: NOT FROM API (shouldn't be there)
230 -----------------------------------------------------------------------------------------------------------------------------
231 */
232 
233 es2panda_AstNode * cachedParentNode;
234 es2panda_Context * cachedContext;
235 
changeParent(es2panda_AstNode * child)236 static void changeParent(es2panda_AstNode *child)
237 {
238     GetImpl()->AstNodeSetParent(cachedContext, child, cachedParentNode);
239 }
240 
SetRightParent(es2panda_AstNode * node,void * arg)241 static void SetRightParent(es2panda_AstNode *node, void *arg)
242 {
243     es2panda_Context *ctx = static_cast<es2panda_Context *>(arg);
244     cachedContext = ctx;
245     cachedParentNode = node;
246 
247     GetImpl()->AstNodeIterateConst(ctx, node, changeParent);
248 }
249 
impl_AstNodeUpdateAll(KNativePointer contextPtr,KNativePointer programPtr)250 KNativePointer impl_AstNodeUpdateAll(KNativePointer contextPtr, KNativePointer programPtr) {
251     auto context = reinterpret_cast<es2panda_Context*>(contextPtr);
252     auto program = reinterpret_cast<es2panda_AstNode*>(programPtr);
253 
254     GetImpl()->AstNodeForEach(program, SetRightParent, context);
255     return program;
256 }
KOALA_INTEROP_2(AstNodeUpdateAll,KNativePointer,KNativePointer,KNativePointer)257 KOALA_INTEROP_2(AstNodeUpdateAll, KNativePointer, KNativePointer, KNativePointer)
258 
259 KNativePointer impl_AstNodeUpdateChildren(KNativePointer contextPtr, KNativePointer nodePtr) {
260     auto context = reinterpret_cast<es2panda_Context*>(contextPtr);
261     auto node = reinterpret_cast<es2panda_AstNode*>(nodePtr);
262     cachedParentNode = node;
263 
264     GetImpl()->AstNodeIterateConst(context, node, changeParent);
265     return node;
266 }
267 KOALA_INTEROP_2(AstNodeUpdateChildren, KNativePointer, KNativePointer, KNativePointer)
268 
269 std::vector<void*> cachedChildren;
270 
visitChild(es2panda_AstNode * node)271 static void visitChild(es2panda_AstNode *node)
272 {
273     cachedChildren.emplace_back(node);
274 }
275 
impl_AstNodeChildren(KNativePointer contextPtr,KNativePointer nodePtr)276 KNativePointer impl_AstNodeChildren(
277     KNativePointer contextPtr,
278     KNativePointer nodePtr
279 ) {
280     auto context = reinterpret_cast<es2panda_Context*>(contextPtr);
281     auto node = reinterpret_cast<es2panda_AstNode*>(nodePtr);
282     cachedContext = context;
283     cachedChildren.clear();
284 
285     GetImpl()->AstNodeIterateConst(context, node, visitChild);
286     return StageArena::clone(cachedChildren);
287 }
288 KOALA_INTEROP_2(AstNodeChildren, KNativePointer, KNativePointer, KNativePointer)
289 
290 /*
291 -----------------------------------------------------------------------------------------------------------------------------
292 */
293