siger-young updated this revision to Diff 366520.
siger-young added a comment.

Using `lua_newuserdata` instead of `lua_newuserdatauv` to support Lua 5.3


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108090/new/

https://reviews.llvm.org/D108090

Files:
  lldb/CMakeLists.txt
  lldb/bindings/lua/CMakeLists.txt
  lldb/bindings/lua/lua-typemaps.swig
  lldb/bindings/lua/lua-wrapper.swig
  lldb/bindings/lua/lua.swig
  lldb/source/API/liblldb-private.exports
  lldb/source/API/liblldb.exports

Index: lldb/source/API/liblldb.exports
===================================================================
--- lldb/source/API/liblldb.exports
+++ lldb/source/API/liblldb.exports
@@ -2,3 +2,4 @@
 _ZNK4lldb*
 init_lld*
 PyInit__lldb*
+luaopen_lldb*
Index: lldb/source/API/liblldb-private.exports
===================================================================
--- lldb/source/API/liblldb-private.exports
+++ lldb/source/API/liblldb-private.exports
@@ -4,3 +4,4 @@
 _ZNK12lldb_private*
 init_lld*
 PyInit__lldb*
+luaopen_lldb*
Index: lldb/bindings/lua/lua.swig
===================================================================
--- lldb/bindings/lua/lua.swig
+++ lldb/bindings/lua/lua.swig
@@ -17,6 +17,10 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "../bindings/lua/lua-swigsafecast.swig"
+
+// required headers for typemaps
+#include "lldb/Host/File.h"
+
 using namespace lldb_private;
 using namespace lldb;
 %}
Index: lldb/bindings/lua/lua-wrapper.swig
===================================================================
--- lldb/bindings/lua/lua-wrapper.swig
+++ lldb/bindings/lua/lua-wrapper.swig
@@ -6,6 +6,19 @@
 
 %}
 
+%runtime %{
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton);
+int LLDBSwigLuaCloseFileHandle(lua_State *L);
+
+#ifdef __cplusplus
+}
+#endif
+%}
+
 %wrapper %{
 
 // This function is called from Lua::CallBreakpointCallback
@@ -88,5 +101,20 @@
    return stop;
 }
 
+SWIGEXPORT void
+LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton) {
+   lua_State *L = (lua_State *)baton;
+
+   lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
+   lua_gettable(L, LUA_REGISTRYINDEX);
+
+   // FIXME: There's no way to report errors back to the user
+   lua_pushstring(L, str);
+   lua_pcall(L, 1, 0, 0);
+}
+
+int LLDBSwigLuaCloseFileHandle(lua_State *L) {
+   return luaL_error(L, "You cannot close a file handle used by lldb.");
+}
 
 %}
Index: lldb/bindings/lua/lua-typemaps.swig
===================================================================
--- lldb/bindings/lua/lua-typemaps.swig
+++ lldb/bindings/lua/lua-typemaps.swig
@@ -12,7 +12,7 @@
 
 // Primitive integer mapping
 %typemap(in,checkfn="lua_isinteger") TYPE
-%{ $1 = (TYPE)lua_tointeger(L, $input); %}
+%{ $1 = ($type)lua_tointeger(L, $input); %}
 %typemap(in,checkfn="lua_isinteger") const TYPE&($basetype temp)
 %{ temp=($basetype)lua_tointeger(L,$input); $1=&temp;%}
 %typemap(out) TYPE
@@ -54,6 +54,7 @@
 LLDB_NUMBER_TYPEMAP(long long);
 LLDB_NUMBER_TYPEMAP(unsigned long long);
 LLDB_NUMBER_TYPEMAP(signed long long);
+LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
 
 %apply unsigned long { size_t };
 %apply const unsigned long & { const size_t & };
@@ -77,7 +78,7 @@
 %typemap(in) (char *dst, size_t dst_len) {
    $2 = luaL_checkinteger(L, $input);
    if ($2 <= 0) {
-       return luaL_error(L, "Positive integer expected");
+      return luaL_error(L, "Positive integer expected");
    }
    $1 = (char *) malloc($2);
 }
@@ -86,6 +87,9 @@
 // as char data instead of byte data.
 %typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
 
+// Also SBProcess::ReadMemory.
+%typemap(in) (void *buf, size_t size) = (char *dst, size_t dst_len);
+
 // Return the char buffer.  Discarding any previous return result
 %typemap(argout) (char *dst, size_t dst_len) {
    lua_pop(L, 1); // Blow away the previous result
@@ -102,4 +106,178 @@
 // as char data instead of byte data.
 %typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
 
+// Also SBProcess::ReadMemory.
+%typemap(argout) (void *buf, size_t size) = (char *dst, size_t dst_len);
+
 //===----------------------------------------------------------------------===//
+
+// Typemap for handling a snprintf-like API like SBThread::GetStopDescription.
+
+%typemap(in) (char *dst_or_null, size_t dst_len) {
+   $2 = luaL_checkinteger(L, $input);
+   if ($2 <= 0) {
+      return luaL_error(L, "Positive integer expected");
+   }
+   $1 = (char *)malloc($2);
+}
+
+%typemap(argout) (char *dst_or_null, size_t dst_len) {
+   lua_pop(L, 1); // Blow away the previous result
+   lua_pushlstring(L, (const char *)$1, $result);
+   free($1);
+   // SWIG_arg was already incremented
+}
+
+//===----------------------------------------------------------------------===//
+
+// Typemap for handling SBModule::GetVersion
+
+%typemap(in) (uint32_t *versions, uint32_t num_versions) {
+   $2 = 99;
+   $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2);
+}
+
+%typemap(argout) (uint32_t *versions, uint32_t num_versions) {
+   uint32_t count = result;
+   if (count >= $2)
+      count = $2;
+   lua_newtable(L);
+   int i = 0;
+   while (i++ < count) {
+      lua_pushinteger(L, $1[i - 1]);
+      lua_seti(L, -2, i);
+   }
+   SWIG_arg++;
+   free($1);
+}
+
+//===----------------------------------------------------------------------===//
+
+// Typemap for handling SBDebugger::SetLoggingCallback
+
+%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
+   $1 = LLDBSwigLuaCallLuaLogOutputCallback;
+   $2 = (void *)L;
+
+   luaL_checktype(L, 2, LUA_TFUNCTION);
+   lua_settop(L, 2);
+
+   lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
+   lua_insert(L, 2);
+   lua_settable(L, LUA_REGISTRYINDEX);
+}
+
+//===----------------------------------------------------------------------===//
+
+// Typemap for handling SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len)
+
+%typemap(in) (const char *cstr, uint32_t cstr_len) {
+   $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
+}
+
+// Typemap for handling SBProcess::PutSTDIN
+
+%typemap(in) (const char *src, size_t src_len) {
+   $1 = (char *)luaL_checklstring(L, $input, &$2);
+}
+
+// Typemap for handling SBProcess::WriteMemory, SBTarget::GetInstructions...
+
+%typemap(in) (const void *buf, size_t size),
+             (const void *data, size_t data_len) {
+   $1 = (void *)luaL_checklstring(L, $input, &$2);
+}
+
+//===----------------------------------------------------------------------===//
+
+// Typemap for handling char ** in SBTarget::LaunchSimple, SBTarget::Launch...
+
+%typemap(in) char ** {
+   if (lua_istable(L, $input)) {
+      size_t size = lua_rawlen(L, $input);
+      $1 = (char **)malloc((size + 1) * sizeof(char *));
+      int i = 0, j = 0;
+      while (i++ < size) {
+         lua_rawgeti(L, $input, i);
+         $1[j++] = (char *)lua_tostring(L, -1);
+         lua_pop(L, 1);
+      }
+      $1[j] = 0;
+   } else if (lua_isnil(L, $input)) {
+      $1 = NULL;
+   }
+}
+
+%typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** {
+   $1 = (lua_istable(L, $input) || lua_isnil(L, $input)) ? 1 : 0;
+}
+
+//===----------------------------------------------------------------------===//
+
+// Typemap for file handles (e.g. used in SBDebugger::SetOutputFile)
+
+%typemap(in) lldb::FileSP {
+   luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE);
+   FileSP file_sp;
+   file_sp = std::make_shared<NativeFile>(p->f, false);
+   if (!file_sp->IsValid())
+      return luaL_error(L, "Invalid file");
+   $1 = file_sp;
+}
+
+%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {
+   $1 = lua_isuserdata(L, $input) ? 1 : 0;
+}
+
+// Typemap for file handles (e.g. used in SBDebugger::GetOutputFileHandle)
+
+%typemap(out) lldb::FileSP {
+   lldb::FileSP &sp = $1;
+   if (sp && sp->IsValid()) {
+      luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
+      p->closef = &LLDBSwigLuaCloseFileHandle;
+      p->f = sp->GetStream();
+      luaL_setmetatable(L, LUA_FILEHANDLE);
+      SWIG_arg++;
+   }
+}
+
+//===----------------------------------------------------------------------===//
+
+// Typemap for SBData::CreateDataFromUInt64Array, SBData::SetDataFromUInt64Array ...
+
+%typemap(in) (uint64_t* array, size_t array_len),
+             (uint32_t* array, size_t array_len),
+             (int64_t* array, size_t array_len),
+             (int32_t* array, size_t array_len),
+             (double* array, size_t array_len) {
+   if (lua_istable(L, $input)) {
+      $2 = lua_rawlen(L, $input);
+      $1 = ($1_ltype)malloc(($2) * sizeof($*1_type));
+      int i = 0, j = 0;
+      while (i++ < $2) {
+         lua_rawgeti(L, $input, i);
+         $1[j++] = ($*1_ltype)lua_tonumber(L, -1);
+         lua_pop(L, 1);
+      }
+   } else if (lua_isnil(L, $input)) {
+      $1 = NULL;
+      $2 = 0;
+   }
+}
+
+//===----------------------------------------------------------------------===//
+
+// Typemap for SBCommandReturnObject::PutCString
+
+%typemap(in) (const char *string, int len) {
+   if (lua_isnil(L, $input)) {
+      $1 = NULL;
+      $2 = 0;
+   }
+   else {
+      $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
+   }
+}
+
+//===----------------------------------------------------------------------===//
\ No newline at end of file
Index: lldb/bindings/lua/CMakeLists.txt
===================================================================
--- lldb/bindings/lua/CMakeLists.txt
+++ lldb/bindings/lua/CMakeLists.txt
@@ -17,3 +17,10 @@
 add_custom_target(swig_wrapper_lua ALL DEPENDS
   ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapLua.cpp
 )
+
+function(create_lua_package swig_target working_dir pkg_dir)
+  cmake_parse_arguments(ARG "NOINIT" "" "FILES" ${ARGN})
+  add_custom_command(TARGET ${swig_target} POST_BUILD VERBATIM
+    COMMAND ${CMAKE_COMMAND} -E make_directory ${pkg_dir}
+    WORKING_DIRECTORY ${working_dir})
+endfunction()
Index: lldb/CMakeLists.txt
===================================================================
--- lldb/CMakeLists.txt
+++ lldb/CMakeLists.txt
@@ -51,6 +51,24 @@
     CACHE STRING "Path where Python modules are installed, relative to install prefix")
 endif ()
 
+if (LLDB_ENABLE_LUA)
+   # FIXME: Lua 5.3 is hardcoded but it should support 5.3+!
+   find_program(Lua_EXECUTABLE lua5.3)
+   if (NOT Lua_EXECUTABLE)
+      message(FATAL_ERROR "Lua executable not found")
+   else ()
+      execute_process(
+         COMMAND ${Lua_EXECUTABLE}
+         -e "for w in string.gmatch(package.cpath, ';?([^;]+);?') do \
+         if string.match(w, '%?%.so') then print(string.sub(w, 1, #w - 4)) break end end"
+         OUTPUT_VARIABLE LLDB_LUA_DEFAULT_INSTALL_PATH
+         OUTPUT_STRIP_TRAILING_WHITESPACE)
+      file(TO_CMAKE_PATH ${LLDB_LUA_DEFAULT_INSTALL_PATH} LLDB_LUA_DEFAULT_INSTALL_PATH)
+      set(LLDB_LUA_INSTALL_PATH ${LLDB_LUA_DEFAULT_INSTALL_PATH}
+         CACHE STRING "Path where Lua modules are installed")
+   endif ()
+endif ()
+
 if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA)
   add_subdirectory(bindings)
 endif ()
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to