1a0d7406aSPedro Tammela%header %{
2a0d7406aSPedro Tammela
3a0d7406aSPedro Tammelatemplate <typename T>
4a0d7406aSPedro Tammelavoid
5a0d7406aSPedro TammelaPushSBClass(lua_State* L, T* obj);
6a0d7406aSPedro Tammela
7a0d7406aSPedro Tammela// This function is called from Lua::CallBreakpointCallback
8a52af6d3SPavel Labathllvm::Expected<bool>
9a52af6d3SPavel Labathlldb_private::LLDBSwigLuaBreakpointCallbackFunction
10a0d7406aSPedro Tammela(
11a0d7406aSPedro Tammela   lua_State *L,
12a0d7406aSPedro Tammela   lldb::StackFrameSP stop_frame_sp,
13532e4203SPedro Tammela   lldb::BreakpointLocationSP bp_loc_sp,
14*82de8df2SPavel Labath   const StructuredDataImpl &extra_args_impl
15a0d7406aSPedro Tammela)
16a0d7406aSPedro Tammela{
17a0d7406aSPedro Tammela   lldb::SBFrame sb_frame(stop_frame_sp);
18a0d7406aSPedro Tammela   lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
19532e4203SPedro Tammela   int nargs = 2;
20532e4203SPedro Tammela
21*82de8df2SPavel Labath   lldb::SBStructuredData extra_args(extra_args_impl);
22a0d7406aSPedro Tammela
23a0d7406aSPedro Tammela   // Push the Lua wrappers
24a0d7406aSPedro Tammela   PushSBClass(L, &sb_frame);
25a0d7406aSPedro Tammela   PushSBClass(L, &sb_bp_loc);
26a0d7406aSPedro Tammela
27*82de8df2SPavel Labath   if (extra_args.IsValid()) {
28*82de8df2SPavel Labath      PushSBClass(L, &extra_args);
29532e4203SPedro Tammela      nargs++;
30532e4203SPedro Tammela   }
31532e4203SPedro Tammela
32a0d7406aSPedro Tammela   // Call into the Lua callback passing 'sb_frame' and 'sb_bp_loc'.
33a0d7406aSPedro Tammela   // Expects a boolean return.
34532e4203SPedro Tammela   if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
35a0d7406aSPedro Tammela      llvm::Error E = llvm::make_error<llvm::StringError>(
36a0d7406aSPedro Tammela            llvm::formatv("{0}\n", lua_tostring(L, -1)),
37a0d7406aSPedro Tammela            llvm::inconvertibleErrorCode());
38a0d7406aSPedro Tammela      // Pop error message from the stack.
39a0d7406aSPedro Tammela      lua_pop(L, 1);
40a0d7406aSPedro Tammela      return std::move(E);
41a0d7406aSPedro Tammela   }
42a0d7406aSPedro Tammela
43a0d7406aSPedro Tammela   // Boolean return from the callback
44a0d7406aSPedro Tammela   bool stop = lua_toboolean(L, -1);
45a0d7406aSPedro Tammela   lua_pop(L, 1);
46a0d7406aSPedro Tammela
47a0d7406aSPedro Tammela   return stop;
48a0d7406aSPedro Tammela}
49a0d7406aSPedro Tammela
50e81ba283SSiger Yang// This function is called from Lua::CallWatchpointCallback
51a52af6d3SPavel Labathllvm::Expected<bool>
52a52af6d3SPavel Labathlldb_private::LLDBSwigLuaWatchpointCallbackFunction
53e81ba283SSiger Yang(
54e81ba283SSiger Yang   lua_State *L,
55e81ba283SSiger Yang   lldb::StackFrameSP stop_frame_sp,
56e81ba283SSiger Yang   lldb::WatchpointSP wp_sp
57e81ba283SSiger Yang)
58e81ba283SSiger Yang{
59e81ba283SSiger Yang   lldb::SBFrame sb_frame(stop_frame_sp);
60e81ba283SSiger Yang   lldb::SBWatchpoint sb_wp(wp_sp);
61e81ba283SSiger Yang   int nargs = 2;
62e81ba283SSiger Yang
63e81ba283SSiger Yang   // Push the Lua wrappers
64e81ba283SSiger Yang   PushSBClass(L, &sb_frame);
65e81ba283SSiger Yang   PushSBClass(L, &sb_wp);
66e81ba283SSiger Yang
67e81ba283SSiger Yang   // Call into the Lua callback passing 'sb_frame' and 'sb_wp'.
68e81ba283SSiger Yang   // Expects a boolean return.
69e81ba283SSiger Yang   if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
70e81ba283SSiger Yang      llvm::Error E = llvm::make_error<llvm::StringError>(
71e81ba283SSiger Yang            llvm::formatv("{0}\n", lua_tostring(L, -1)),
72e81ba283SSiger Yang            llvm::inconvertibleErrorCode());
73e81ba283SSiger Yang      // Pop error message from the stack.
74e81ba283SSiger Yang      lua_pop(L, 1);
75e81ba283SSiger Yang      return std::move(E);
76e81ba283SSiger Yang   }
77e81ba283SSiger Yang
78e81ba283SSiger Yang   // Boolean return from the callback
79e81ba283SSiger Yang   bool stop = lua_toboolean(L, -1);
80e81ba283SSiger Yang   lua_pop(L, 1);
81e81ba283SSiger Yang
82e81ba283SSiger Yang   return stop;
83e81ba283SSiger Yang}
84e81ba283SSiger Yang
85a52af6d3SPavel Labathstatic void
8667f94e5aSSiger YangLLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton) {
8767f94e5aSSiger Yang   lua_State *L = (lua_State *)baton;
8867f94e5aSSiger Yang
8967f94e5aSSiger Yang   lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
9067f94e5aSSiger Yang   lua_gettable(L, LUA_REGISTRYINDEX);
9167f94e5aSSiger Yang
9267f94e5aSSiger Yang   // FIXME: There's no way to report errors back to the user
9367f94e5aSSiger Yang   lua_pushstring(L, str);
9467f94e5aSSiger Yang   lua_pcall(L, 1, 0, 0);
9567f94e5aSSiger Yang}
9667f94e5aSSiger Yang
97a52af6d3SPavel Labathstatic int LLDBSwigLuaCloseFileHandle(lua_State *L) {
9867f94e5aSSiger Yang   return luaL_error(L, "You cannot close a file handle used by lldb.");
9967f94e5aSSiger Yang}
100a0d7406aSPedro Tammela
101a0d7406aSPedro Tammela%}
102