1130d950cSDimitry Andric%include <typemaps.i> 2e8d8bef9SDimitry Andric 3e8d8bef9SDimitry Andric// FIXME: We need to port more typemaps from Python 4e8d8bef9SDimitry Andric 5e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 6e8d8bef9SDimitry Andric 7e8d8bef9SDimitry Andric// In Lua 5.3 and beyond the VM supports integers, so we need to remap 8e8d8bef9SDimitry Andric// SWIG's internal handling of integers. 9e8d8bef9SDimitry Andric 10e8d8bef9SDimitry Andric 11e8d8bef9SDimitry Andric%define LLDB_NUMBER_TYPEMAP(TYPE) 12e8d8bef9SDimitry Andric 13e8d8bef9SDimitry Andric// Primitive integer mapping 14e8d8bef9SDimitry Andric%typemap(in,checkfn="lua_isinteger") TYPE 15*349cc55cSDimitry Andric%{ $1 = ($type)lua_tointeger(L, $input); %} 16e8d8bef9SDimitry Andric%typemap(in,checkfn="lua_isinteger") const TYPE&($basetype temp) 17e8d8bef9SDimitry Andric%{ temp=($basetype)lua_tointeger(L,$input); $1=&temp;%} 18e8d8bef9SDimitry Andric%typemap(out) TYPE 19e8d8bef9SDimitry Andric%{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%} 20e8d8bef9SDimitry Andric%typemap(out) const TYPE& 21e8d8bef9SDimitry Andric%{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%} 22e8d8bef9SDimitry Andric 23e8d8bef9SDimitry Andric// Pointer and reference mapping 24e8d8bef9SDimitry Andric%typemap(in,checkfn="lua_isinteger") TYPE *INPUT($*ltype temp), TYPE &INPUT($*ltype temp) 25e8d8bef9SDimitry Andric%{ temp = ($*ltype)lua_tointeger(L,$input); 26e8d8bef9SDimitry Andric $1 = &temp; %} 27e8d8bef9SDimitry Andric%typemap(in, numinputs=0) TYPE *OUTPUT ($*ltype temp) 28e8d8bef9SDimitry Andric%{ $1 = &temp; %} 29e8d8bef9SDimitry Andric%typemap(argout) TYPE *OUTPUT 30e8d8bef9SDimitry Andric%{ lua_pushinteger(L, (lua_Integer) *$1); SWIG_arg++;%} 31e8d8bef9SDimitry Andric%typemap(in) TYPE *INOUT = TYPE *INPUT; 32e8d8bef9SDimitry Andric%typemap(argout) TYPE *INOUT = TYPE *OUTPUT; 33e8d8bef9SDimitry Andric%typemap(in) TYPE &OUTPUT = TYPE *OUTPUT; 34e8d8bef9SDimitry Andric%typemap(argout) TYPE &OUTPUT = TYPE *OUTPUT; 35e8d8bef9SDimitry Andric%typemap(in) TYPE &INOUT = TYPE *INPUT; 36e8d8bef9SDimitry Andric%typemap(argout) TYPE &INOUT = TYPE *OUTPUT; 37e8d8bef9SDimitry Andric%typemap(in,checkfn="lua_isinteger") const TYPE *INPUT($*ltype temp) 38e8d8bef9SDimitry Andric%{ temp = ($*ltype)lua_tointeger(L,$input); 39e8d8bef9SDimitry Andric $1 = &temp; %} 40e8d8bef9SDimitry Andric 41e8d8bef9SDimitry Andric%enddef // LLDB_NUMBER_TYPEMAP 42e8d8bef9SDimitry Andric 43e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(unsigned char); 44e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(signed char); 45e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(short); 46e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(unsigned short); 47e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(signed short); 48e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(int); 49e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(unsigned int); 50e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(signed int); 51e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(long); 52e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(unsigned long); 53e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(signed long); 54e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(long long); 55e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(unsigned long long); 56e8d8bef9SDimitry AndricLLDB_NUMBER_TYPEMAP(signed long long); 57*349cc55cSDimitry AndricLLDB_NUMBER_TYPEMAP(enum SWIGTYPE); 58e8d8bef9SDimitry Andric 59e8d8bef9SDimitry Andric%apply unsigned long { size_t }; 60e8d8bef9SDimitry Andric%apply const unsigned long & { const size_t & }; 61e8d8bef9SDimitry Andric%apply long { ssize_t }; 62e8d8bef9SDimitry Andric%apply const long & { const ssize_t & }; 63e8d8bef9SDimitry Andric 64e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 65e8d8bef9SDimitry Andric 66e8d8bef9SDimitry Andric// FIXME: 67e8d8bef9SDimitry Andric// Ideally all the typemaps should be revisited in a future SB API revision. 68e8d8bef9SDimitry Andric// Typemaps, usually, modifies the function signatures and might spawn 69e8d8bef9SDimitry Andric// different LLDB APIs across languages (C++, Python, Lua...). 70e8d8bef9SDimitry Andric// Historically, typemaps have been used to replace SWIG's deficiencies, 71e8d8bef9SDimitry Andric// but SWIG itself evolved and some API design choices are now redundant. 72e8d8bef9SDimitry Andric 73e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 74e8d8bef9SDimitry Andric 75e8d8bef9SDimitry Andric// Typemap definitions to allow SWIG to properly handle char buffer. 76e8d8bef9SDimitry Andric 77e8d8bef9SDimitry Andric// typemap for a char buffer 78e8d8bef9SDimitry Andric%typemap(in) (char *dst, size_t dst_len) { 79e8d8bef9SDimitry Andric $2 = luaL_checkinteger(L, $input); 80e8d8bef9SDimitry Andric if ($2 <= 0) { 81e8d8bef9SDimitry Andric return luaL_error(L, "Positive integer expected"); 82e8d8bef9SDimitry Andric } 83e8d8bef9SDimitry Andric $1 = (char *) malloc($2); 84e8d8bef9SDimitry Andric} 85e8d8bef9SDimitry Andric 86e8d8bef9SDimitry Andric// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 87e8d8bef9SDimitry Andric// as char data instead of byte data. 88e8d8bef9SDimitry Andric%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 89e8d8bef9SDimitry Andric 90*349cc55cSDimitry Andric// Also SBProcess::ReadMemory. 91*349cc55cSDimitry Andric%typemap(in) (void *buf, size_t size) = (char *dst, size_t dst_len); 92*349cc55cSDimitry Andric 93e8d8bef9SDimitry Andric// Return the char buffer. Discarding any previous return result 94e8d8bef9SDimitry Andric%typemap(argout) (char *dst, size_t dst_len) { 95e8d8bef9SDimitry Andric lua_pop(L, 1); // Blow away the previous result 96e8d8bef9SDimitry Andric if ($result == 0) { 97e8d8bef9SDimitry Andric lua_pushliteral(L, ""); 98e8d8bef9SDimitry Andric } else { 99e8d8bef9SDimitry Andric lua_pushlstring(L, (const char *)$1, $result); 100e8d8bef9SDimitry Andric } 101e8d8bef9SDimitry Andric free($1); 102e8d8bef9SDimitry Andric // SWIG_arg was already incremented 103e8d8bef9SDimitry Andric} 104e8d8bef9SDimitry Andric 105e8d8bef9SDimitry Andric// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 106e8d8bef9SDimitry Andric// as char data instead of byte data. 107e8d8bef9SDimitry Andric%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 108e8d8bef9SDimitry Andric 109*349cc55cSDimitry Andric// Also SBProcess::ReadMemory. 110*349cc55cSDimitry Andric%typemap(argout) (void *buf, size_t size) = (char *dst, size_t dst_len); 111*349cc55cSDimitry Andric 112*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 113*349cc55cSDimitry Andric 114*349cc55cSDimitry Andric// Typemap for handling a snprintf-like API like SBThread::GetStopDescription. 115*349cc55cSDimitry Andric 116*349cc55cSDimitry Andric%typemap(in) (char *dst_or_null, size_t dst_len) { 117*349cc55cSDimitry Andric $2 = luaL_checkinteger(L, $input); 118*349cc55cSDimitry Andric if ($2 <= 0) { 119*349cc55cSDimitry Andric return luaL_error(L, "Positive integer expected"); 120*349cc55cSDimitry Andric } 121*349cc55cSDimitry Andric $1 = (char *)malloc($2); 122*349cc55cSDimitry Andric} 123*349cc55cSDimitry Andric 124*349cc55cSDimitry Andric%typemap(argout) (char *dst_or_null, size_t dst_len) { 125*349cc55cSDimitry Andric lua_pop(L, 1); // Blow away the previous result 126*349cc55cSDimitry Andric lua_pushlstring(L, (const char *)$1, $result); 127*349cc55cSDimitry Andric free($1); 128*349cc55cSDimitry Andric // SWIG_arg was already incremented 129*349cc55cSDimitry Andric} 130*349cc55cSDimitry Andric 131*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 132*349cc55cSDimitry Andric 133*349cc55cSDimitry Andric// Typemap for handling SBModule::GetVersion 134*349cc55cSDimitry Andric 135*349cc55cSDimitry Andric%typemap(in) (uint32_t *versions, uint32_t num_versions) { 136*349cc55cSDimitry Andric $2 = 99; 137*349cc55cSDimitry Andric $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2); 138*349cc55cSDimitry Andric} 139*349cc55cSDimitry Andric 140*349cc55cSDimitry Andric%typemap(argout) (uint32_t *versions, uint32_t num_versions) { 141*349cc55cSDimitry Andric uint32_t count = result; 142*349cc55cSDimitry Andric if (count >= $2) 143*349cc55cSDimitry Andric count = $2; 144*349cc55cSDimitry Andric lua_newtable(L); 145*349cc55cSDimitry Andric int i = 0; 146*349cc55cSDimitry Andric while (i++ < count) { 147*349cc55cSDimitry Andric lua_pushinteger(L, $1[i - 1]); 148*349cc55cSDimitry Andric lua_seti(L, -2, i); 149*349cc55cSDimitry Andric } 150*349cc55cSDimitry Andric SWIG_arg++; 151*349cc55cSDimitry Andric free($1); 152*349cc55cSDimitry Andric} 153*349cc55cSDimitry Andric 154*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 155*349cc55cSDimitry Andric 156*349cc55cSDimitry Andric// Typemap for handling SBDebugger::SetLoggingCallback 157*349cc55cSDimitry Andric 158*349cc55cSDimitry Andric%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { 159*349cc55cSDimitry Andric $1 = LLDBSwigLuaCallLuaLogOutputCallback; 160*349cc55cSDimitry Andric $2 = (void *)L; 161*349cc55cSDimitry Andric 162*349cc55cSDimitry Andric luaL_checktype(L, 2, LUA_TFUNCTION); 163*349cc55cSDimitry Andric lua_settop(L, 2); 164*349cc55cSDimitry Andric 165*349cc55cSDimitry Andric lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback); 166*349cc55cSDimitry Andric lua_insert(L, 2); 167*349cc55cSDimitry Andric lua_settable(L, LUA_REGISTRYINDEX); 168*349cc55cSDimitry Andric} 169*349cc55cSDimitry Andric 170*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 171*349cc55cSDimitry Andric 172*349cc55cSDimitry Andric// Typemap for handling SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len) 173*349cc55cSDimitry Andric 174*349cc55cSDimitry Andric%typemap(in) (const char *cstr, uint32_t cstr_len) { 175*349cc55cSDimitry Andric $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2); 176*349cc55cSDimitry Andric} 177*349cc55cSDimitry Andric 178*349cc55cSDimitry Andric// Typemap for handling SBProcess::PutSTDIN 179*349cc55cSDimitry Andric 180*349cc55cSDimitry Andric%typemap(in) (const char *src, size_t src_len) { 181*349cc55cSDimitry Andric $1 = (char *)luaL_checklstring(L, $input, &$2); 182*349cc55cSDimitry Andric} 183*349cc55cSDimitry Andric 184*349cc55cSDimitry Andric// Typemap for handling SBProcess::WriteMemory, SBTarget::GetInstructions... 185*349cc55cSDimitry Andric 186*349cc55cSDimitry Andric%typemap(in) (const void *buf, size_t size), 187*349cc55cSDimitry Andric (const void *data, size_t data_len) { 188*349cc55cSDimitry Andric $1 = (void *)luaL_checklstring(L, $input, &$2); 189*349cc55cSDimitry Andric} 190*349cc55cSDimitry Andric 191*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 192*349cc55cSDimitry Andric 193*349cc55cSDimitry Andric// Typemap for handling char ** in SBTarget::LaunchSimple, SBTarget::Launch... 194*349cc55cSDimitry Andric 195*349cc55cSDimitry Andric// It should accept a Lua table of strings, for stuff like "argv" and "envp". 196*349cc55cSDimitry Andric 197*349cc55cSDimitry Andric%typemap(in) char ** { 198*349cc55cSDimitry Andric if (lua_istable(L, $input)) { 199*349cc55cSDimitry Andric size_t size = lua_rawlen(L, $input); 200*349cc55cSDimitry Andric $1 = (char **)malloc((size + 1) * sizeof(char *)); 201*349cc55cSDimitry Andric int i = 0, j = 0; 202*349cc55cSDimitry Andric while (i++ < size) { 203*349cc55cSDimitry Andric lua_rawgeti(L, $input, i); 204*349cc55cSDimitry Andric if (!lua_isstring(L, -1)) { 205*349cc55cSDimitry Andric // if current element cannot be converted to string, raise an error 206*349cc55cSDimitry Andric lua_pop(L, 1); 207*349cc55cSDimitry Andric return luaL_error(L, "List should only contain strings"); 208*349cc55cSDimitry Andric } 209*349cc55cSDimitry Andric $1[j++] = (char *)lua_tostring(L, -1); 210*349cc55cSDimitry Andric lua_pop(L, 1); 211*349cc55cSDimitry Andric } 212*349cc55cSDimitry Andric $1[j] = 0; 213*349cc55cSDimitry Andric } else if (lua_isnil(L, $input)) { 214*349cc55cSDimitry Andric // "nil" is also acceptable, equivalent as an empty table 215*349cc55cSDimitry Andric $1 = NULL; 216*349cc55cSDimitry Andric } else { 217*349cc55cSDimitry Andric return luaL_error(L, "A list of strings expected"); 218*349cc55cSDimitry Andric } 219*349cc55cSDimitry Andric} 220*349cc55cSDimitry Andric 221*349cc55cSDimitry Andric%typemap(freearg) char ** { 222*349cc55cSDimitry Andric free((char *) $1); 223*349cc55cSDimitry Andric} 224*349cc55cSDimitry Andric 225*349cc55cSDimitry Andric%typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** { 226*349cc55cSDimitry Andric $1 = (lua_istable(L, $input) || lua_isnil(L, $input)); 227*349cc55cSDimitry Andric} 228*349cc55cSDimitry Andric 229*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 230*349cc55cSDimitry Andric 231*349cc55cSDimitry Andric// Typemap for file handles (e.g. used in SBDebugger::SetOutputFile) 232*349cc55cSDimitry Andric 233*349cc55cSDimitry Andric%typemap(in) lldb::FileSP { 234*349cc55cSDimitry Andric luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE); 235*349cc55cSDimitry Andric lldb::FileSP file_sp; 236*349cc55cSDimitry Andric file_sp = std::make_shared<lldb_private::NativeFile>(p->f, false); 237*349cc55cSDimitry Andric if (!file_sp->IsValid()) 238*349cc55cSDimitry Andric return luaL_error(L, "Invalid file"); 239*349cc55cSDimitry Andric $1 = file_sp; 240*349cc55cSDimitry Andric} 241*349cc55cSDimitry Andric 242*349cc55cSDimitry Andric%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP { 243*349cc55cSDimitry Andric $1 = (lua_isuserdata(L, $input)) && 244*349cc55cSDimitry Andric (luaL_testudata(L, $input, LUA_FILEHANDLE) != nullptr); 245*349cc55cSDimitry Andric} 246*349cc55cSDimitry Andric 247*349cc55cSDimitry Andric// Typemap for file handles (e.g. used in SBDebugger::GetOutputFileHandle) 248*349cc55cSDimitry Andric 249*349cc55cSDimitry Andric%typemap(out) lldb::FileSP { 250*349cc55cSDimitry Andric lldb::FileSP &sp = $1; 251*349cc55cSDimitry Andric if (sp && sp->IsValid()) { 252*349cc55cSDimitry Andric luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream)); 253*349cc55cSDimitry Andric p->closef = &LLDBSwigLuaCloseFileHandle; 254*349cc55cSDimitry Andric p->f = sp->GetStream(); 255*349cc55cSDimitry Andric luaL_setmetatable(L, LUA_FILEHANDLE); 256*349cc55cSDimitry Andric SWIG_arg++; 257*349cc55cSDimitry Andric } 258*349cc55cSDimitry Andric} 259*349cc55cSDimitry Andric 260*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 261*349cc55cSDimitry Andric 262*349cc55cSDimitry Andric// Typemap for SBData::CreateDataFromUInt64Array, SBData::SetDataFromUInt64Array ... 263*349cc55cSDimitry Andric 264*349cc55cSDimitry Andric%typemap(in) (uint64_t* array, size_t array_len), 265*349cc55cSDimitry Andric (uint32_t* array, size_t array_len), 266*349cc55cSDimitry Andric (int64_t* array, size_t array_len), 267*349cc55cSDimitry Andric (int32_t* array, size_t array_len), 268*349cc55cSDimitry Andric (double* array, size_t array_len) { 269*349cc55cSDimitry Andric if (lua_istable(L, $input)) { 270*349cc55cSDimitry Andric // It should accept a table of numbers. 271*349cc55cSDimitry Andric $2 = lua_rawlen(L, $input); 272*349cc55cSDimitry Andric $1 = ($1_ltype)malloc(($2) * sizeof($*1_type)); 273*349cc55cSDimitry Andric int i = 0, j = 0; 274*349cc55cSDimitry Andric while (i++ < $2) { 275*349cc55cSDimitry Andric lua_rawgeti(L, $input, i); 276*349cc55cSDimitry Andric if (!lua_isnumber(L, -1)) { 277*349cc55cSDimitry Andric // if current element cannot be converted to number, raise an error 278*349cc55cSDimitry Andric lua_pop(L, 1); 279*349cc55cSDimitry Andric return luaL_error(L, "List should only contain numbers"); 280*349cc55cSDimitry Andric } 281*349cc55cSDimitry Andric $1[j++] = ($*1_ltype)lua_tonumber(L, -1); 282*349cc55cSDimitry Andric lua_pop(L, 1); 283*349cc55cSDimitry Andric } 284*349cc55cSDimitry Andric } else if (lua_isnil(L, $input)) { 285*349cc55cSDimitry Andric // "nil" is also acceptable, equivalent as an empty table 286*349cc55cSDimitry Andric $1 = NULL; 287*349cc55cSDimitry Andric $2 = 0; 288*349cc55cSDimitry Andric } else { 289*349cc55cSDimitry Andric // else raise an error 290*349cc55cSDimitry Andric return luaL_error(L, "A list of numbers expected."); 291*349cc55cSDimitry Andric } 292*349cc55cSDimitry Andric} 293*349cc55cSDimitry Andric 294*349cc55cSDimitry Andric%typemap(freearg) (uint64_t* array, size_t array_len), 295*349cc55cSDimitry Andric (uint32_t* array, size_t array_len), 296*349cc55cSDimitry Andric (int64_t* array, size_t array_len), 297*349cc55cSDimitry Andric (int32_t* array, size_t array_len), 298*349cc55cSDimitry Andric (double* array, size_t array_len) { 299*349cc55cSDimitry Andric free($1); 300*349cc55cSDimitry Andric} 301*349cc55cSDimitry Andric 302*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 303*349cc55cSDimitry Andric 304*349cc55cSDimitry Andric// Typemap for SBCommandReturnObject::PutCString 305*349cc55cSDimitry Andric 306*349cc55cSDimitry Andric%typemap(in) (const char *string, int len) { 307*349cc55cSDimitry Andric if (lua_isnil(L, $input)) { 308*349cc55cSDimitry Andric $1 = NULL; 309*349cc55cSDimitry Andric $2 = 0; 310*349cc55cSDimitry Andric } 311*349cc55cSDimitry Andric else { 312*349cc55cSDimitry Andric $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2); 313*349cc55cSDimitry Andric } 314*349cc55cSDimitry Andric} 315*349cc55cSDimitry Andric 316e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 317