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
8*a52af6d3SPavel Labathllvm::Expected<bool>
9*a52af6d3SPavel Labathlldb_private::LLDBSwigLuaBreakpointCallbackFunction
10a0d7406aSPedro Tammela(
11a0d7406aSPedro Tammela   lua_State *L,
12a0d7406aSPedro Tammela   lldb::StackFrameSP stop_frame_sp,
13532e4203SPedro Tammela   lldb::BreakpointLocationSP bp_loc_sp,
14532e4203SPedro Tammela   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
21532e4203SPedro Tammela   llvm::Optional<lldb::SBStructuredData> extra_args;
22532e4203SPedro Tammela   if (extra_args_impl)
23532e4203SPedro Tammela      extra_args = lldb::SBStructuredData(extra_args_impl);
24a0d7406aSPedro Tammela
25a0d7406aSPedro Tammela   // Push the Lua wrappers
26a0d7406aSPedro Tammela   PushSBClass(L, &sb_frame);
27a0d7406aSPedro Tammela   PushSBClass(L, &sb_bp_loc);
28a0d7406aSPedro Tammela
29532e4203SPedro Tammela   if (extra_args.hasValue()) {
30532e4203SPedro Tammela      PushSBClass(L, extra_args.getPointer());
31532e4203SPedro Tammela      nargs++;
32532e4203SPedro Tammela   }
33532e4203SPedro Tammela
34a0d7406aSPedro Tammela   // Call into the Lua callback passing 'sb_frame' and 'sb_bp_loc'.
35a0d7406aSPedro Tammela   // Expects a boolean return.
36532e4203SPedro Tammela   if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
37a0d7406aSPedro Tammela      llvm::Error E = llvm::make_error<llvm::StringError>(
38a0d7406aSPedro Tammela            llvm::formatv("{0}\n", lua_tostring(L, -1)),
39a0d7406aSPedro Tammela            llvm::inconvertibleErrorCode());
40a0d7406aSPedro Tammela      // Pop error message from the stack.
41a0d7406aSPedro Tammela      lua_pop(L, 1);
42a0d7406aSPedro Tammela      return std::move(E);
43a0d7406aSPedro Tammela   }
44a0d7406aSPedro Tammela
45a0d7406aSPedro Tammela   // Boolean return from the callback
46a0d7406aSPedro Tammela   bool stop = lua_toboolean(L, -1);
47a0d7406aSPedro Tammela   lua_pop(L, 1);
48a0d7406aSPedro Tammela
49a0d7406aSPedro Tammela   return stop;
50a0d7406aSPedro Tammela}
51a0d7406aSPedro Tammela
52e81ba283SSiger Yang// This function is called from Lua::CallWatchpointCallback
53*a52af6d3SPavel Labathllvm::Expected<bool>
54*a52af6d3SPavel Labathlldb_private::LLDBSwigLuaWatchpointCallbackFunction
55e81ba283SSiger Yang(
56e81ba283SSiger Yang   lua_State *L,
57e81ba283SSiger Yang   lldb::StackFrameSP stop_frame_sp,
58e81ba283SSiger Yang   lldb::WatchpointSP wp_sp
59e81ba283SSiger Yang)
60e81ba283SSiger Yang{
61e81ba283SSiger Yang   lldb::SBFrame sb_frame(stop_frame_sp);
62e81ba283SSiger Yang   lldb::SBWatchpoint sb_wp(wp_sp);
63e81ba283SSiger Yang   int nargs = 2;
64e81ba283SSiger Yang
65e81ba283SSiger Yang   // Push the Lua wrappers
66e81ba283SSiger Yang   PushSBClass(L, &sb_frame);
67e81ba283SSiger Yang   PushSBClass(L, &sb_wp);
68e81ba283SSiger Yang
69e81ba283SSiger Yang   // Call into the Lua callback passing 'sb_frame' and 'sb_wp'.
70e81ba283SSiger Yang   // Expects a boolean return.
71e81ba283SSiger Yang   if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
72e81ba283SSiger Yang      llvm::Error E = llvm::make_error<llvm::StringError>(
73e81ba283SSiger Yang            llvm::formatv("{0}\n", lua_tostring(L, -1)),
74e81ba283SSiger Yang            llvm::inconvertibleErrorCode());
75e81ba283SSiger Yang      // Pop error message from the stack.
76e81ba283SSiger Yang      lua_pop(L, 1);
77e81ba283SSiger Yang      return std::move(E);
78e81ba283SSiger Yang   }
79e81ba283SSiger Yang
80e81ba283SSiger Yang   // Boolean return from the callback
81e81ba283SSiger Yang   bool stop = lua_toboolean(L, -1);
82e81ba283SSiger Yang   lua_pop(L, 1);
83e81ba283SSiger Yang
84e81ba283SSiger Yang   return stop;
85e81ba283SSiger Yang}
86e81ba283SSiger Yang
87*a52af6d3SPavel Labathstatic void
8867f94e5aSSiger YangLLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton) {
8967f94e5aSSiger Yang   lua_State *L = (lua_State *)baton;
9067f94e5aSSiger Yang
9167f94e5aSSiger Yang   lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
9267f94e5aSSiger Yang   lua_gettable(L, LUA_REGISTRYINDEX);
9367f94e5aSSiger Yang
9467f94e5aSSiger Yang   // FIXME: There's no way to report errors back to the user
9567f94e5aSSiger Yang   lua_pushstring(L, str);
9667f94e5aSSiger Yang   lua_pcall(L, 1, 0, 0);
9767f94e5aSSiger Yang}
9867f94e5aSSiger Yang
99*a52af6d3SPavel Labathstatic int LLDBSwigLuaCloseFileHandle(lua_State *L) {
10067f94e5aSSiger Yang   return luaL_error(L, "You cannot close a file handle used by lldb.");
10167f94e5aSSiger Yang}
102a0d7406aSPedro Tammela
103a0d7406aSPedro Tammela%}
104