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 15349cc55cSDimitry 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); 57349cc55cSDimitry 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 90349cc55cSDimitry Andric// Also SBProcess::ReadMemory. 91349cc55cSDimitry Andric%typemap(in) (void *buf, size_t size) = (char *dst, size_t dst_len); 92349cc55cSDimitry 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 109349cc55cSDimitry Andric// Also SBProcess::ReadMemory. 110349cc55cSDimitry Andric%typemap(argout) (void *buf, size_t size) = (char *dst, size_t dst_len); 111349cc55cSDimitry Andric 112349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 113349cc55cSDimitry Andric 114349cc55cSDimitry Andric// Typemap for handling a snprintf-like API like SBThread::GetStopDescription. 115349cc55cSDimitry Andric 116349cc55cSDimitry Andric%typemap(in) (char *dst_or_null, size_t dst_len) { 117349cc55cSDimitry Andric $2 = luaL_checkinteger(L, $input); 118349cc55cSDimitry Andric if ($2 <= 0) { 119349cc55cSDimitry Andric return luaL_error(L, "Positive integer expected"); 120349cc55cSDimitry Andric } 121349cc55cSDimitry Andric $1 = (char *)malloc($2); 122349cc55cSDimitry Andric} 123349cc55cSDimitry Andric 124349cc55cSDimitry Andric%typemap(argout) (char *dst_or_null, size_t dst_len) { 125349cc55cSDimitry Andric lua_pop(L, 1); // Blow away the previous result 126349cc55cSDimitry Andric lua_pushlstring(L, (const char *)$1, $result); 127349cc55cSDimitry Andric free($1); 128349cc55cSDimitry Andric // SWIG_arg was already incremented 129349cc55cSDimitry Andric} 130349cc55cSDimitry Andric 131349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 132349cc55cSDimitry Andric 133349cc55cSDimitry Andric// Typemap for handling SBModule::GetVersion 134349cc55cSDimitry Andric 135349cc55cSDimitry Andric%typemap(in) (uint32_t *versions, uint32_t num_versions) { 136349cc55cSDimitry Andric $2 = 99; 137349cc55cSDimitry Andric $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2); 138349cc55cSDimitry Andric} 139349cc55cSDimitry Andric 140349cc55cSDimitry Andric%typemap(argout) (uint32_t *versions, uint32_t num_versions) { 141349cc55cSDimitry Andric uint32_t count = result; 142349cc55cSDimitry Andric if (count >= $2) 143349cc55cSDimitry Andric count = $2; 144349cc55cSDimitry Andric lua_newtable(L); 145349cc55cSDimitry Andric int i = 0; 146349cc55cSDimitry Andric while (i++ < count) { 147349cc55cSDimitry Andric lua_pushinteger(L, $1[i - 1]); 148349cc55cSDimitry Andric lua_seti(L, -2, i); 149349cc55cSDimitry Andric } 150349cc55cSDimitry Andric SWIG_arg++; 151349cc55cSDimitry Andric free($1); 152349cc55cSDimitry Andric} 153349cc55cSDimitry Andric 154349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 155349cc55cSDimitry Andric 156349cc55cSDimitry Andric// Typemap for handling SBDebugger::SetLoggingCallback 157349cc55cSDimitry Andric 158349cc55cSDimitry Andric%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { 159349cc55cSDimitry Andric $1 = LLDBSwigLuaCallLuaLogOutputCallback; 160349cc55cSDimitry Andric $2 = (void *)L; 161349cc55cSDimitry Andric 162349cc55cSDimitry Andric luaL_checktype(L, 2, LUA_TFUNCTION); 163349cc55cSDimitry Andric lua_settop(L, 2); 164349cc55cSDimitry Andric 165349cc55cSDimitry Andric lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback); 166349cc55cSDimitry Andric lua_insert(L, 2); 167349cc55cSDimitry Andric lua_settable(L, LUA_REGISTRYINDEX); 168349cc55cSDimitry Andric} 169349cc55cSDimitry Andric 170349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 171349cc55cSDimitry Andric 172349cc55cSDimitry Andric// Typemap for handling SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len) 173349cc55cSDimitry Andric 174349cc55cSDimitry Andric%typemap(in) (const char *cstr, uint32_t cstr_len) { 175349cc55cSDimitry Andric $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2); 176349cc55cSDimitry Andric} 177349cc55cSDimitry Andric 178349cc55cSDimitry Andric// Typemap for handling SBProcess::PutSTDIN 179349cc55cSDimitry Andric 180349cc55cSDimitry Andric%typemap(in) (const char *src, size_t src_len) { 181349cc55cSDimitry Andric $1 = (char *)luaL_checklstring(L, $input, &$2); 182349cc55cSDimitry Andric} 183349cc55cSDimitry Andric 184349cc55cSDimitry Andric// Typemap for handling SBProcess::WriteMemory, SBTarget::GetInstructions... 185349cc55cSDimitry Andric 186349cc55cSDimitry Andric%typemap(in) (const void *buf, size_t size), 187349cc55cSDimitry Andric (const void *data, size_t data_len) { 188349cc55cSDimitry Andric $1 = (void *)luaL_checklstring(L, $input, &$2); 189349cc55cSDimitry Andric} 190349cc55cSDimitry Andric 191349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 192349cc55cSDimitry Andric 193349cc55cSDimitry Andric// Typemap for handling char ** in SBTarget::LaunchSimple, SBTarget::Launch... 194349cc55cSDimitry Andric 195349cc55cSDimitry Andric// It should accept a Lua table of strings, for stuff like "argv" and "envp". 196349cc55cSDimitry Andric 197349cc55cSDimitry Andric%typemap(in) char ** { 198349cc55cSDimitry Andric if (lua_istable(L, $input)) { 199349cc55cSDimitry Andric size_t size = lua_rawlen(L, $input); 200349cc55cSDimitry Andric $1 = (char **)malloc((size + 1) * sizeof(char *)); 201349cc55cSDimitry Andric int i = 0, j = 0; 202349cc55cSDimitry Andric while (i++ < size) { 203349cc55cSDimitry Andric lua_rawgeti(L, $input, i); 204349cc55cSDimitry Andric if (!lua_isstring(L, -1)) { 205349cc55cSDimitry Andric // if current element cannot be converted to string, raise an error 206349cc55cSDimitry Andric lua_pop(L, 1); 207349cc55cSDimitry Andric return luaL_error(L, "List should only contain strings"); 208349cc55cSDimitry Andric } 209349cc55cSDimitry Andric $1[j++] = (char *)lua_tostring(L, -1); 210349cc55cSDimitry Andric lua_pop(L, 1); 211349cc55cSDimitry Andric } 212349cc55cSDimitry Andric $1[j] = 0; 213349cc55cSDimitry Andric } else if (lua_isnil(L, $input)) { 214349cc55cSDimitry Andric // "nil" is also acceptable, equivalent as an empty table 215349cc55cSDimitry Andric $1 = NULL; 216349cc55cSDimitry Andric } else { 217349cc55cSDimitry Andric return luaL_error(L, "A list of strings expected"); 218349cc55cSDimitry Andric } 219349cc55cSDimitry Andric} 220349cc55cSDimitry Andric 221349cc55cSDimitry Andric%typemap(freearg) char ** { 222349cc55cSDimitry Andric free((char *) $1); 223349cc55cSDimitry Andric} 224349cc55cSDimitry Andric 225349cc55cSDimitry Andric%typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** { 226349cc55cSDimitry Andric $1 = (lua_istable(L, $input) || lua_isnil(L, $input)); 227349cc55cSDimitry Andric} 228349cc55cSDimitry Andric 229349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 230349cc55cSDimitry Andric 231349cc55cSDimitry Andric// Typemap for file handles (e.g. used in SBDebugger::SetOutputFile) 232349cc55cSDimitry Andric 233349cc55cSDimitry Andric%typemap(in) lldb::FileSP { 234349cc55cSDimitry Andric luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE); 235349cc55cSDimitry Andric lldb::FileSP file_sp; 236349cc55cSDimitry Andric file_sp = std::make_shared<lldb_private::NativeFile>(p->f, false); 237349cc55cSDimitry Andric if (!file_sp->IsValid()) 238349cc55cSDimitry Andric return luaL_error(L, "Invalid file"); 239349cc55cSDimitry Andric $1 = file_sp; 240349cc55cSDimitry Andric} 241349cc55cSDimitry Andric 242349cc55cSDimitry Andric%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP { 243349cc55cSDimitry Andric $1 = (lua_isuserdata(L, $input)) && 244349cc55cSDimitry Andric (luaL_testudata(L, $input, LUA_FILEHANDLE) != nullptr); 245349cc55cSDimitry Andric} 246349cc55cSDimitry Andric 247349cc55cSDimitry Andric// Typemap for file handles (e.g. used in SBDebugger::GetOutputFileHandle) 248349cc55cSDimitry Andric 249349cc55cSDimitry Andric%typemap(out) lldb::FileSP { 250*bdd1243dSDimitry Andric lldb::FileSP sp = $1; 251349cc55cSDimitry Andric if (sp && sp->IsValid()) { 252349cc55cSDimitry Andric luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream)); 253349cc55cSDimitry Andric p->closef = &LLDBSwigLuaCloseFileHandle; 254349cc55cSDimitry Andric p->f = sp->GetStream(); 255349cc55cSDimitry Andric luaL_setmetatable(L, LUA_FILEHANDLE); 256349cc55cSDimitry Andric SWIG_arg++; 257349cc55cSDimitry Andric } 258349cc55cSDimitry Andric} 259349cc55cSDimitry Andric 260349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 261349cc55cSDimitry Andric 262349cc55cSDimitry Andric// Typemap for SBData::CreateDataFromUInt64Array, SBData::SetDataFromUInt64Array ... 263349cc55cSDimitry Andric 264349cc55cSDimitry Andric%typemap(in) (uint64_t* array, size_t array_len), 265349cc55cSDimitry Andric (uint32_t* array, size_t array_len), 266349cc55cSDimitry Andric (int64_t* array, size_t array_len), 267349cc55cSDimitry Andric (int32_t* array, size_t array_len), 268349cc55cSDimitry Andric (double* array, size_t array_len) { 269349cc55cSDimitry Andric if (lua_istable(L, $input)) { 270349cc55cSDimitry Andric // It should accept a table of numbers. 271349cc55cSDimitry Andric $2 = lua_rawlen(L, $input); 272349cc55cSDimitry Andric $1 = ($1_ltype)malloc(($2) * sizeof($*1_type)); 273349cc55cSDimitry Andric int i = 0, j = 0; 274349cc55cSDimitry Andric while (i++ < $2) { 275349cc55cSDimitry Andric lua_rawgeti(L, $input, i); 276349cc55cSDimitry Andric if (!lua_isnumber(L, -1)) { 277349cc55cSDimitry Andric // if current element cannot be converted to number, raise an error 278349cc55cSDimitry Andric lua_pop(L, 1); 279349cc55cSDimitry Andric return luaL_error(L, "List should only contain numbers"); 280349cc55cSDimitry Andric } 281349cc55cSDimitry Andric $1[j++] = ($*1_ltype) lua_tonumber(L, -1); 282349cc55cSDimitry Andric lua_pop(L, 1); 283349cc55cSDimitry Andric } 284349cc55cSDimitry Andric } else if (lua_isnil(L, $input)) { 285349cc55cSDimitry Andric // "nil" is also acceptable, equivalent as an empty table 286349cc55cSDimitry Andric $1 = NULL; 287349cc55cSDimitry Andric $2 = 0; 288349cc55cSDimitry Andric } else { 289349cc55cSDimitry Andric // else raise an error 290349cc55cSDimitry Andric return luaL_error(L, "A list of numbers expected."); 291349cc55cSDimitry Andric } 292349cc55cSDimitry Andric} 293349cc55cSDimitry Andric 294349cc55cSDimitry Andric%typemap(freearg) (uint64_t* array, size_t array_len), 295349cc55cSDimitry Andric (uint32_t* array, size_t array_len), 296349cc55cSDimitry Andric (int64_t* array, size_t array_len), 297349cc55cSDimitry Andric (int32_t* array, size_t array_len), 298349cc55cSDimitry Andric (double* array, size_t array_len) { 299349cc55cSDimitry Andric free($1); 300349cc55cSDimitry Andric} 301349cc55cSDimitry Andric 302349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 303349cc55cSDimitry Andric 304349cc55cSDimitry Andric// Typemap for SBCommandReturnObject::PutCString 305349cc55cSDimitry Andric 306349cc55cSDimitry Andric%typemap(in) (const char *string, int len) { 307349cc55cSDimitry Andric if (lua_isnil(L, $input)) { 308349cc55cSDimitry Andric $1 = NULL; 309349cc55cSDimitry Andric $2 = 0; 3100eae32dcSDimitry Andric } else { 311349cc55cSDimitry Andric $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2); 312349cc55cSDimitry Andric } 313349cc55cSDimitry Andric} 314349cc55cSDimitry Andric 315e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 316