brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.8 KiB · 51a9247 Raw
335 lines · plain
1%include <typemaps.i>2 3// FIXME: We need to port more typemaps from Python4 5//===----------------------------------------------------------------------===//6 7// In Lua 5.3 and beyond the VM supports integers, so we need to remap8// SWIG's internal handling of integers.9 10 11%define LLDB_NUMBER_TYPEMAP(TYPE)12 13// Primitive integer mapping14%typemap(in,checkfn="lua_isinteger") TYPE15%{ $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;%}18%typemap(out) TYPE19%{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%}20%typemap(out) const TYPE&21%{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%}22 23// Pointer and reference mapping24%typemap(in,checkfn="lua_isinteger") TYPE *INPUT($*ltype temp), TYPE &INPUT($*ltype temp)25%{ temp = ($*ltype)lua_tointeger(L,$input);26   $1 = &temp; %}27%typemap(in, numinputs=0) TYPE *OUTPUT ($*ltype temp)28%{ $1 = &temp; %}29%typemap(argout) TYPE *OUTPUT30%{  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);39   $1 = &temp; %}40 41%enddef // LLDB_NUMBER_TYPEMAP42 43LLDB_NUMBER_TYPEMAP(unsigned char);44LLDB_NUMBER_TYPEMAP(signed char);45LLDB_NUMBER_TYPEMAP(short);46LLDB_NUMBER_TYPEMAP(unsigned short);47LLDB_NUMBER_TYPEMAP(signed short);48LLDB_NUMBER_TYPEMAP(int);49LLDB_NUMBER_TYPEMAP(unsigned int);50LLDB_NUMBER_TYPEMAP(signed int);51LLDB_NUMBER_TYPEMAP(long);52LLDB_NUMBER_TYPEMAP(unsigned long);53LLDB_NUMBER_TYPEMAP(signed long);54LLDB_NUMBER_TYPEMAP(long long);55LLDB_NUMBER_TYPEMAP(unsigned long long);56LLDB_NUMBER_TYPEMAP(signed long long);57LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);58 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 & };63 64//===----------------------------------------------------------------------===//65 66// FIXME:67//  Ideally all the typemaps should be revisited in a future SB API revision.68//  Typemaps, usually, modifies the function signatures and might spawn69//  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.72 73//===----------------------------------------------------------------------===//74 75// Typemap definitions to allow SWIG to properly handle char buffer.76 77// typemap for a char buffer78%typemap(in) (char *dst, size_t dst_len) {79  $2 = luaL_checkinteger(L, $input);80  if ($2 <= 0) {81    return luaL_error(L, "Positive integer expected");82  }83  $1 = (char *)malloc($2);84}85 86// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated87// as char data instead of byte data.88%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);89 90// Also SBProcess::ReadMemory.91%typemap(in) (void *buf, size_t size) = (char *dst, size_t dst_len);92 93// Return the char buffer.  Discarding any previous return result94%typemap(argout) (char *dst, size_t dst_len) {95  lua_pop(L, 1); // Blow away the previous result96  if ($result == 0) {97    lua_pushliteral(L, "");98  } else {99    lua_pushlstring(L, (const char *)$1, $result);100  }101  free($1);102  // SWIG_arg was already incremented103}104 105// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated106// as char data instead of byte data.107%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);108 109// Also SBProcess::ReadMemory.110%typemap(argout) (void *buf, size_t size) = (char *dst, size_t dst_len);111 112//===----------------------------------------------------------------------===//113 114// Typemap for handling a snprintf-like API like SBThread::GetStopDescription.115 116%typemap(in) (char *dst_or_null, size_t dst_len) {117  $2 = luaL_checkinteger(L, $input);118  if ($2 <= 0) {119    return luaL_error(L, "Positive integer expected");120  }121  $1 = (char *)malloc($2);122}123 124// Disable default type checking for this method to avoid SWIG dispatch issues.125//126// Problem: SBThread::GetStopDescription has two overloads:127//   1. GetStopDescription(char* dst_or_null, size_t dst_len)128//   2. GetStopDescription(lldb::SBStream& stream)129//130// SWIG generates a dispatch function to select the correct overload based on argument types.131// see https://www.swig.org/Doc4.0/SWIGDocumentation.html#Typemaps_overloading.132// However, this dispatcher doesn't consider typemaps that transform function signatures.133//134// In lua, our typemap converts GetStopDescription(char*, size_t) to GetStopDescription(int).135// The dispatcher still checks against the original (char*, size_t) signature instead of136// the transformed (int) signature, causing type matching to fail.137// This only affects SBThread::GetStopDescription since the type check also matches138// the argument name, which is unique to this function.139%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) (char *dst_or_null, size_t dst_len) ""140 141%typemap(argout) (char *dst_or_null, size_t dst_len) {142  lua_pop(L, 1); // Blow away the previous result143  llvm::StringRef ref($1);144  lua_pushlstring(L, (const char *)$1, ref.size());145  free($1);146  // SWIG_arg was already incremented147}148 149//===----------------------------------------------------------------------===//150 151// Typemap for handling SBModule::GetVersion152 153%typemap(in) (uint32_t *versions, uint32_t num_versions) {154  $2 = 99;155  $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2);156}157 158%typemap(argout) (uint32_t *versions, uint32_t num_versions) {159  uint32_t count = result;160  if (count >= $2)161    count = $2;162  lua_newtable(L);163  int i = 0;164  while (i++ < count) {165    lua_pushinteger(L, $1[i - 1]);166    lua_seti(L, -2, i);167  }168  SWIG_arg++;169  free($1);170}171 172//===----------------------------------------------------------------------===//173 174// Typemap for handling SBDebugger::SetLoggingCallback175 176%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {177  $1 = LLDBSwigLuaCallLuaLogOutputCallback;178  $2 = (void *)L;179 180  luaL_checktype(L, 2, LUA_TFUNCTION);181  lua_settop(L, 2);182 183  lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);184  lua_insert(L, 2);185  lua_settable(L, LUA_REGISTRYINDEX);186}187 188//===----------------------------------------------------------------------===//189 190// Typemap for handling SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len)191 192%typemap(in) (const char *cstr, uint32_t cstr_len) {193  $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);194}195 196// Typemap for handling SBProcess::PutSTDIN197 198%typemap(in) (const char *src, size_t src_len) {199  $1 = (char *)luaL_checklstring(L, $input, &$2);200}201 202// Typemap for handling SBProcess::WriteMemory, SBTarget::GetInstructions...203 204%typemap(in) (const void *buf, size_t size),205             (const void *data, size_t data_len) {206  $1 = (void *)luaL_checklstring(L, $input, &$2);207}208 209//===----------------------------------------------------------------------===//210 211// Typemap for handling char ** in SBTarget::LaunchSimple, SBTarget::Launch...212 213// It should accept a Lua table of strings, for stuff like "argv" and "envp".214 215%typemap(in) char ** {216  if (lua_istable(L, $input)) {217    size_t size = lua_rawlen(L, $input);218    $1 = (char **)malloc((size + 1) * sizeof(char *));219    int i = 0, j = 0;220    while (i++ < size) {221      lua_rawgeti(L, $input, i);222      if (!lua_isstring(L, -1)) {223        // if current element cannot be converted to string, raise an error224        lua_pop(L, 1);225        return luaL_error(L, "List should only contain strings");226      }227      $1[j++] = (char *)lua_tostring(L, -1);228      lua_pop(L, 1);229    }230    $1[j] = 0;231  } else if (lua_isnil(L, $input)) {232    // "nil" is also acceptable, equivalent as an empty table233    $1 = NULL;234  } else {235    return luaL_error(L, "A list of strings expected");236  }237}238 239%typemap(freearg) char ** {240  free((char *) $1);241}242 243%typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** {244  $1 = (lua_istable(L, $input) || lua_isnil(L, $input));245}246 247//===----------------------------------------------------------------------===//248 249// Typemap for file handles (e.g. used in SBDebugger::SetOutputFile)250 251%typemap(in) lldb::FileSP {252  luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE);253  lldb::FileSP file_sp;254  file_sp = std::make_shared<lldb_private::NativeFile>(255      p->f, lldb_private::NativeFile::eOpenOptionWriteOnly, false);256  if (!file_sp->IsValid())257    return luaL_error(L, "Invalid file");258  $1 = file_sp;259}260 261%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {262  $1 = (lua_isuserdata(L, $input)) &&263       (luaL_testudata(L, $input, LUA_FILEHANDLE) != nullptr);264}265 266// Typemap for file handles (e.g. used in SBDebugger::GetOutputFileHandle)267 268%typemap(out) lldb::FileSP {269  lldb::FileSP sp = $1;270  if (sp && sp->IsValid()) {271    luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));272    p->closef = &LLDBSwigLuaCloseFileHandle;273    p->f = sp->GetStream();274    luaL_setmetatable(L, LUA_FILEHANDLE);275    SWIG_arg++;276  }277}278 279//===----------------------------------------------------------------------===//280 281// Typemap for SBData::CreateDataFromUInt64Array, SBData::SetDataFromUInt64Array ...282 283%typemap(in) (uint64_t* array, size_t array_len),284             (uint32_t* array, size_t array_len),285             (int64_t* array, size_t array_len),286             (int32_t* array, size_t array_len),287             (double* array, size_t array_len) {288  if (lua_istable(L, $input)) {289    // It should accept a table of numbers.290    $2 = lua_rawlen(L, $input);291    $1 = ($1_ltype)malloc(($2) * sizeof($*1_type));292    int i = 0, j = 0;293    while (i++ < $2) {294      lua_rawgeti(L, $input, i);295      if (!lua_isnumber(L, -1)) {296        // if current element cannot be converted to number, raise an error297        lua_pop(L, 1);298        return luaL_error(L, "List should only contain numbers");299      }300      $1[j++] = ($*1_ltype) lua_tonumber(L, -1);301      lua_pop(L, 1);302    }303  } else if (lua_isnil(L, $input)) {304    // "nil" is also acceptable, equivalent as an empty table305    $1 = NULL;306    $2 = 0;307  } else {308    // else raise an error309    return luaL_error(L, "A list of numbers expected.");310  }311}312 313%typemap(freearg) (uint64_t* array, size_t array_len),314             (uint32_t* array, size_t array_len),315             (int64_t* array, size_t array_len),316             (int32_t* array, size_t array_len),317             (double* array, size_t array_len) {318  free($1);319}320 321//===----------------------------------------------------------------------===//322 323// Typemap for SBCommandReturnObject::PutCString324 325%typemap(in) (const char *string, int len) {326  if (lua_isnil(L, $input)) {327    $1 = NULL;328    $2 = 0;329  } else {330    $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);331  }332}333 334//===----------------------------------------------------------------------===//335