3 // FIXME: We need to port more typemaps from Python
5 //===----------------------------------------------------------------------===//
7 // In Lua 5.3 and beyond the VM supports integers, so we need to remap
8 // SWIG's internal handling of integers.
11 %define LLDB_NUMBER_TYPEMAP(TYPE)
13 // Primitive integer mapping
14 %typemap(in,checkfn="lua_isinteger") TYPE
15 %{ $1 = ($type)lua_tointeger(L, $input); %}
16 %typemap(in,checkfn="lua_isinteger") const TYPE&($basetype temp)
17 %{ temp=($basetype)lua_tointeger(L,$input); $1=&temp;%}
19 %{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%}
20 %typemap(out) const TYPE&
21 %{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%}
23 // Pointer and reference mapping
24 %typemap(in,checkfn="lua_isinteger") TYPE *INPUT($*ltype temp), TYPE &INPUT($*ltype temp)
25 %{ temp = ($*ltype)lua_tointeger(L,$input);
27 %typemap(in, numinputs=0) TYPE *OUTPUT ($*ltype temp)
29 %typemap(argout) TYPE *OUTPUT
30 %{ lua_pushinteger(L, (lua_Integer) *$1); SWIG_arg++;%}
31 %typemap(in) TYPE *INOUT = TYPE *INPUT;
32 %typemap(argout) TYPE *INOUT = TYPE *OUTPUT;
33 %typemap(in) TYPE &OUTPUT = TYPE *OUTPUT;
34 %typemap(argout) TYPE &OUTPUT = TYPE *OUTPUT;
35 %typemap(in) TYPE &INOUT = TYPE *INPUT;
36 %typemap(argout) TYPE &INOUT = TYPE *OUTPUT;
37 %typemap(in,checkfn="lua_isinteger") const TYPE *INPUT($*ltype temp)
38 %{ temp = ($*ltype)lua_tointeger(L,$input);
41 %enddef // LLDB_NUMBER_TYPEMAP
43 LLDB_NUMBER_TYPEMAP(unsigned char);
44 LLDB_NUMBER_TYPEMAP(signed char);
45 LLDB_NUMBER_TYPEMAP(short);
46 LLDB_NUMBER_TYPEMAP(unsigned short);
47 LLDB_NUMBER_TYPEMAP(signed short);
48 LLDB_NUMBER_TYPEMAP(int);
49 LLDB_NUMBER_TYPEMAP(unsigned int);
50 LLDB_NUMBER_TYPEMAP(signed int);
51 LLDB_NUMBER_TYPEMAP(long);
52 LLDB_NUMBER_TYPEMAP(unsigned long);
53 LLDB_NUMBER_TYPEMAP(signed long);
54 LLDB_NUMBER_TYPEMAP(long long);
55 LLDB_NUMBER_TYPEMAP(unsigned long long);
56 LLDB_NUMBER_TYPEMAP(signed long long);
57 LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
59 %apply unsigned long { size_t };
60 %apply const unsigned long & { const size_t & };
61 %apply long { ssize_t };
62 %apply const long & { const ssize_t & };
64 //===----------------------------------------------------------------------===//
67 // Ideally all the typemaps should be revisited in a future SB API revision.
68 // Typemaps, usually, modifies the function signatures and might spawn
69 // different LLDB APIs across languages (C++, Python, Lua...).
70 // Historically, typemaps have been used to replace SWIG's deficiencies,
71 // but SWIG itself evolved and some API design choices are now redundant.
73 //===----------------------------------------------------------------------===//
75 // Typemap definitions to allow SWIG to properly handle char buffer.
77 // typemap for a char buffer
78 %typemap(in) (char *dst, size_t dst_len) {
79 $2 = luaL_checkinteger(L, $input);
81 return luaL_error(L, "Positive integer expected");
83 $1 = (char *)malloc($2);
86 // SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
87 // as char data instead of byte data.
88 %typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
90 // Also SBProcess::ReadMemory.
91 %typemap(in) (void *buf, size_t size) = (char *dst, size_t dst_len);
93 // Return the char buffer. Discarding any previous return result
94 %typemap(argout) (char *dst, size_t dst_len) {
95 lua_pop(L, 1); // Blow away the previous result
97 lua_pushliteral(L, "");
99 lua_pushlstring(L, (const char *)$1, $result);
102 // SWIG_arg was already incremented
105 // SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
106 // as char data instead of byte data.
107 %typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
109 // Also SBProcess::ReadMemory.
110 %typemap(argout) (void *buf, size_t size) = (char *dst, size_t dst_len);
112 //===----------------------------------------------------------------------===//
114 // Typemap for handling a snprintf-like API like SBThread::GetStopDescription.
116 %typemap(in) (char *dst_or_null, size_t dst_len) {
117 $2 = luaL_checkinteger(L, $input);
119 return luaL_error(L, "Positive integer expected");
121 $1 = (char *)malloc($2);
124 %typemap(argout) (char *dst_or_null, size_t dst_len) {
125 lua_pop(L, 1); // Blow away the previous result
126 lua_pushlstring(L, (const char *)$1, $result);
128 // SWIG_arg was already incremented
131 //===----------------------------------------------------------------------===//
133 // Typemap for handling SBModule::GetVersion
135 %typemap(in) (uint32_t *versions, uint32_t num_versions) {
137 $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2);
140 %typemap(argout) (uint32_t *versions, uint32_t num_versions) {
141 uint32_t count = result;
146 while (i++ < count) {
147 lua_pushinteger(L, $1[i - 1]);
154 //===----------------------------------------------------------------------===//
156 // Typemap for handling SBDebugger::SetLoggingCallback
158 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
159 $1 = LLDBSwigLuaCallLuaLogOutputCallback;
162 luaL_checktype(L, 2, LUA_TFUNCTION);
165 lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
167 lua_settable(L, LUA_REGISTRYINDEX);
170 //===----------------------------------------------------------------------===//
172 // Typemap for handling SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len)
174 %typemap(in) (const char *cstr, uint32_t cstr_len) {
175 $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
178 // Typemap for handling SBProcess::PutSTDIN
180 %typemap(in) (const char *src, size_t src_len) {
181 $1 = (char *)luaL_checklstring(L, $input, &$2);
184 // Typemap for handling SBProcess::WriteMemory, SBTarget::GetInstructions...
186 %typemap(in) (const void *buf, size_t size),
187 (const void *data, size_t data_len) {
188 $1 = (void *)luaL_checklstring(L, $input, &$2);
191 //===----------------------------------------------------------------------===//
193 // Typemap for handling char ** in SBTarget::LaunchSimple, SBTarget::Launch...
195 // It should accept a Lua table of strings, for stuff like "argv" and "envp".
197 %typemap(in) char ** {
198 if (lua_istable(L, $input)) {
199 size_t size = lua_rawlen(L, $input);
200 $1 = (char **)malloc((size + 1) * sizeof(char *));
203 lua_rawgeti(L, $input, i);
204 if (!lua_isstring(L, -1)) {
205 // if current element cannot be converted to string, raise an error
207 return luaL_error(L, "List should only contain strings");
209 $1[j++] = (char *)lua_tostring(L, -1);
213 } else if (lua_isnil(L, $input)) {
214 // "nil" is also acceptable, equivalent as an empty table
217 return luaL_error(L, "A list of strings expected");
221 %typemap(freearg) char ** {
225 %typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** {
226 $1 = (lua_istable(L, $input) || lua_isnil(L, $input));
229 //===----------------------------------------------------------------------===//
231 // Typemap for file handles (e.g. used in SBDebugger::SetOutputFile)
233 %typemap(in) lldb::FileSP {
234 luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE);
235 lldb::FileSP file_sp;
236 file_sp = std::make_shared<lldb_private::NativeFile>(p->f, false);
237 if (!file_sp->IsValid())
238 return luaL_error(L, "Invalid file");
242 %typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {
243 $1 = (lua_isuserdata(L, $input)) &&
244 (luaL_testudata(L, $input, LUA_FILEHANDLE) != nullptr);
247 // Typemap for file handles (e.g. used in SBDebugger::GetOutputFileHandle)
249 %typemap(out) lldb::FileSP {
250 lldb::FileSP sp = $1;
251 if (sp && sp->IsValid()) {
252 luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
253 p->closef = &LLDBSwigLuaCloseFileHandle;
254 p->f = sp->GetStream();
255 luaL_setmetatable(L, LUA_FILEHANDLE);
260 //===----------------------------------------------------------------------===//
262 // Typemap for SBData::CreateDataFromUInt64Array, SBData::SetDataFromUInt64Array ...
264 %typemap(in) (uint64_t* array, size_t array_len),
265 (uint32_t* array, size_t array_len),
266 (int64_t* array, size_t array_len),
267 (int32_t* array, size_t array_len),
268 (double* array, size_t array_len) {
269 if (lua_istable(L, $input)) {
270 // It should accept a table of numbers.
271 $2 = lua_rawlen(L, $input);
272 $1 = ($1_ltype)malloc(($2) * sizeof($*1_type));
275 lua_rawgeti(L, $input, i);
276 if (!lua_isnumber(L, -1)) {
277 // if current element cannot be converted to number, raise an error
279 return luaL_error(L, "List should only contain numbers");
281 $1[j++] = ($*1_ltype) lua_tonumber(L, -1);
284 } else if (lua_isnil(L, $input)) {
285 // "nil" is also acceptable, equivalent as an empty table
289 // else raise an error
290 return luaL_error(L, "A list of numbers expected.");
294 %typemap(freearg) (uint64_t* array, size_t array_len),
295 (uint32_t* array, size_t array_len),
296 (int64_t* array, size_t array_len),
297 (int32_t* array, size_t array_len),
298 (double* array, size_t array_len) {
302 //===----------------------------------------------------------------------===//
304 // Typemap for SBCommandReturnObject::PutCString
306 %typemap(in) (const char *string, int len) {
307 if (lua_isnil(L, $input)) {
311 $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
315 //===----------------------------------------------------------------------===//