hchunhui / librime-lua

Extending RIME with Lua scripts
BSD 3-Clause "New" or "Revised" License
359 stars 45 forks source link

LuaObj::pushdata<L, {}) 是否要避開 core dump #306

Open shewer opened 10 months ago

shewer commented 10 months ago

@hchunhui

1 LuaObj::pushdata(L, {} ); // 是否要避開 pass or pushnil

2 LuaObj 增加 nildata type

class LuaObj {
public:
  ~LuaObj();

  static void pushdata(lua_State *L, std::shared_ptr<LuaObj> &o);
  static std::shared_ptr<LuaObj> todata(lua_State *L, int i);
  static std::shared_ptr<LuaObj> nildata(lua_State *L);
  int type();

private:
  LuaObj(lua_State *L, int i);
  lua_State *L_;
  int id_;
};

 void LuaObj::pushdata(lua_State *L, std::shared_ptr<LuaObj> &o) {
-  lua_rawgeti(L, LUA_REGISTRYINDEX, o->id_);
+  if (o)
+    lua_rawgeti(L, LUA_REGISTRYINDEX, o->id_);
+  else
+    luaL_error(L,
+        "Error: LuaObj::pushdata(*L, std::shared_ptr::<LuaObj>): #1 expected not nullptr");
 }

 std::shared_ptr<LuaObj> LuaObj::todata(lua_State *L, int i) {
   return std::shared_ptr<LuaObj>(new LuaObj(L, i));
 }
+// (+1, -1 , v)
+std::shared_ptr<LuaObj> LuaObj::nildata(lua_State *L) {
+  lua_pushnil(L);
+  return std::shared_ptr<LuaObj>(new LuaObj(L, lua_gettop(L)));
+}
+// (+1, -1, v)
+int LuaObj::type() {
+  lua_rawgeti(L_, LUA_REGISTRYINDEX, id_);
+  int res = lua_type(L_, -1);
+  lua_pop(L_, 1);
+  return res;
+}

image

hchunhui commented 10 months ago

我认为必要性不大。shared_ptr<LuaObj> 是方便 C++ 传递或存储任意 lua 对象的类型,本身只应该从 LuaObj::todata() 得到。满足这个约定的情况下不可能得到空的 pointer。

hchunhui commented 10 months ago

LuaObj 已经通过 private 的方式禁止私自构造了,但是的确没有防止 {} 这种方式得到一个空指针。如果做得更好的话,可以用类似 https://stackoverflow.com/questions/41955232/shared-ptr-that-cannot-be-null 弄一个 shared_reference<LuaObj> ,这样 {} 就会不能通过编译。