1 /*
2 * Copyright (c) 2025 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 <string>
18 #include <iostream>
19 #include "public/es2panda_lib.h"
20 #include "dynamic-loader.h"
21
22 // NOLINTBEGIN
23
24 using std::string, std::cout, std::endl, std::vector;
25
26 static es2panda_Impl const *impl = nullptr;
27
28 #ifdef _WIN32
29 #include <windows.h>
30 #define PLUGIN_DIR "windows_host_tools"
31 #define LIB_PREFIX "lib"
32 #define LIB_SUFFIX ".dll"
33 #else
34 #include <dlfcn.h>
35
36 #ifdef __x86_64__
37 #define PLUGIN_DIR "linux_host_tools"
38 #else
39 #define PLUGIN_DIR "linux_arm64_host_tools"
40 #endif
41
42 #define LIB_PREFIX "lib"
43 #define LIB_SUFFIX ".so"
44 #endif
45
46 const char *LIB_ES2PANDA_PUBLIC = LIB_PREFIX "es2panda_public" LIB_SUFFIX;
47
FindLibrary()48 void *FindLibrary()
49 {
50 std::string libraryName;
51 char *envValue = getenv("PANDA_SDK_PATH");
52 if (envValue) {
53 libraryName = string(envValue) + ("/" PLUGIN_DIR "/lib/") + LIB_ES2PANDA_PUBLIC;
54 } else {
55 if (g_pandaLibPath == "") {
56 libraryName = LIB_ES2PANDA_PUBLIC;
57 } else {
58 libraryName = g_pandaLibPath + "/" + LIB_ES2PANDA_PUBLIC;
59 }
60 }
61 return LoadLibrary(libraryName);
62 }
63
GetPublicImpl()64 const es2panda_Impl *GetPublicImpl()
65 {
66 if (impl) {
67 return impl;
68 }
69 auto library = FindLibrary();
70 if (!library) {
71 std::cout << "Cannot find " << LIB_ES2PANDA_PUBLIC << endl;
72 }
73 auto symbol = FindSymbol(library, "es2panda_GetImpl");
74 if (!symbol) {
75 std::cout << "Cannot find Impl Entry point" << endl;
76 }
77 impl = reinterpret_cast<es2panda_Impl *(*)(int)>(symbol)(ES2PANDA_LIB_VERSION);
78 return impl;
79 }
80
GetString(KStringPtr ptr)81 std::string GetString(KStringPtr ptr)
82 {
83 return ptr.data();
84 }
85
GetStringCopy(KStringPtr & ptr)86 char *GetStringCopy(KStringPtr &ptr)
87 {
88 return strdup(ptr.c_str());
89 }
90
UnpackUInt(const KByte * bytes)91 inline KUInt UnpackUInt(const KByte *bytes)
92 {
93 return (bytes[0] | (bytes[1] << 8U) | (bytes[2U] << 16U) | (bytes[3U] << 24U));
94 }
95
GetStringView(KStringPtr & ptr)96 inline std::string_view GetStringView(KStringPtr &ptr)
97 {
98 return std::string_view(ptr.c_str(), static_cast<size_t>(ptr.length()));
99 }
100
impl_CreateConfig(KInt argc,KStringArray argvPtr,KStringPtr & pandaLibPath)101 KNativePointer impl_CreateConfig(KInt argc, KStringArray argvPtr, KStringPtr &pandaLibPath)
102 {
103 const std::size_t HEADER_LEN = 4;
104 g_pandaLibPath = GetStringView(pandaLibPath);
105 const char **argv = new const char *[static_cast<unsigned int>(argc)];
106 std::size_t position = HEADER_LEN;
107 std::size_t strLen;
108 for (std::size_t i = 0; i < static_cast<std::size_t>(argc); ++i) {
109 strLen = UnpackUInt(argvPtr + position);
110 position += HEADER_LEN;
111 argv[i] = strdup(std::string(reinterpret_cast<const char *>(argvPtr + position), strLen).c_str());
112 position += strLen;
113 }
114 return GetPublicImpl()->CreateConfig(argc, argv);
115 }
TS_INTEROP_3(CreateConfig,KNativePointer,KInt,KStringArray,KStringPtr)116 TS_INTEROP_3(CreateConfig, KNativePointer, KInt, KStringArray, KStringPtr)
117
118 KNativePointer impl_DestroyConfig(KNativePointer configPtr)
119 {
120 auto config = reinterpret_cast<es2panda_Config *>(configPtr);
121 GetPublicImpl()->DestroyConfig(config);
122 return nullptr;
123 }
TS_INTEROP_1(DestroyConfig,KNativePointer,KNativePointer)124 TS_INTEROP_1(DestroyConfig, KNativePointer, KNativePointer)
125
126 KNativePointer impl_DestroyContext(KNativePointer contextPtr)
127 {
128 auto context = reinterpret_cast<es2panda_Context *>(contextPtr);
129 GetPublicImpl()->DestroyContext(context);
130 return nullptr;
131 }
132 TS_INTEROP_1(DestroyContext, KNativePointer, KNativePointer)
133
134 // NOLINTEND
135