예제 #1
0
// Expects: Function, followed by narg arguments, on top of the stack.
// Calls pcall with traceback error handler, removes error handler.
// Error is left on top of the stack.
// Returns the error code, and the stack index at which the return values start.
inline std::tuple<int, int>
pcall_helper(lua_State * L, int narg, int nret) noexcept {
  PRIMER_ASSERT(lua_gettop(L) >= (1 + narg),
                "Not enough arguments on stack for pcall!");
  PRIMER_ASSERT(lua_isfunction(L, -1 - narg), "Missing function for pcall!");
  primer::get_error_handler(L);
  lua_insert(L, -2 - narg);
  const int error_handler_index = lua_absindex(L, -2 - narg);
  const int result_code = lua_pcall(L, narg, nret, error_handler_index);
  lua_remove(L, error_handler_index);

  return std::tuple<int, int>{result_code, error_handler_index};
}
예제 #2
0
T
unsigned_to_signed(typename std::make_unsigned<T>::type x) {
  using U = decltype(x);

  constexpr T max = std::numeric_limits<T>::max();
  constexpr T min = std::numeric_limits<T>::min();

  if (x <= static_cast<U>(max)) { return static_cast<T>(x); }

  if (x >= static_cast<U>(min)) { return static_cast<T>(x - min) + min; }

  PRIMER_ASSERT(false, "Bad unsigned -> signed integer conversion! x = " << x);
  return 0;
}
예제 #3
0
void
fcn_call(expected<T> & result, lua_State * L, int narg) {
  int err_code;
  int results_idx;

  std::tie(err_code, results_idx) =
    detail::pcall_helper(L, narg, return_helper<T>::nrets);
  if (err_code != LUA_OK) {
    result = primer::pop_error(L, err_code);
  } else {
    return_helper<T>::pop(L, results_idx, result);
  }

  PRIMER_ASSERT(lua_gettop(L) == (results_idx - 1),
                "hmm stack discipline error");
}
예제 #4
0
// Expects: Function, followed by narg arguments, on top of the stack.
// Calls lua_resume. If an error occurs, calls the traceback error handler,
// removes error handler. Error is left on top of the stack.
// Returns the error code, and the stack index at which the return values start.
inline std::tuple<int, int>
resume_helper(lua_State * L, int narg) noexcept {
  PRIMER_ASSERT(lua_gettop(L) >= (narg),
                "Not enough arguments on stack for resume!");

  const int result_index = lua_absindex(L, -1 - narg);

  const int result_code = lua_resume(L, nullptr, narg);
  if ((result_code != LUA_OK) && (result_code != LUA_YIELD)) {
    primer::get_error_handler(L);
    lua_insert(L, -2);
    lua_call(L, 1, 1);
  }

  return std::tuple<int, int>{result_code, result_index};
}