Skip to content

Chaining and garbage collection #319

@bolshakov-a

Description

@bolshakov-a

Lua GC erroneously (?) deletes an object when Lua still holds a reference on it obtained through a chain of method calls. E. g.:

#include <lua.hpp>
#include <LuaBridge/LuaBridge.h>

#include <iostream>

struct A {
  ~A() { i = -1; }
  int i = 0;
  A& fn() { i = 5; return *this; }
  int getI() const { return i; }
};

A getA() { return A{}; }

void test() {
  auto pState = luaL_newstate();
  luaL_openlibs(pState);

  luabridge::getGlobalNamespace(pState)
    .addFunction("getA", getA)
    .beginClass<A>("A")
      .addFunction("fn", &A::fn)
      .addFunction("getI", &A::getI)
    .endClass();

  static const char prog[] = R"(
local a1 = getA():fn()
collectgarbage("collect")
print(a1:getI())
)";

  luaL_loadbuffer(pState, prog, sizeof(prog) - 1, 0);
  lua_call(pState, 0, 0, 0);
  lua_close(pState);
}

The program outputs -1 (or some garbage if additional allocations were performed later), which means destructor of A was called before a1:getI() call. If the line local a1 = getA():fn() is replaced by

local a1 = getA()
a1:fn()

the output becomes 5, as expected initially.

Is it a bug of LuaBridge, or Lua itself, or such a chaining is not allowed for some reasons?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions