1a0d7406aSPedro Tammela%header %{
2a0d7406aSPedro Tammela
3a0d7406aSPedro Tammelatemplate <typename T>
4a0d7406aSPedro Tammelavoid
5a0d7406aSPedro TammelaPushSBClass(lua_State* L, T* obj);
6a0d7406aSPedro Tammela
7a0d7406aSPedro Tammela%}
8a0d7406aSPedro Tammela
9*67f94e5aSSiger Yang%runtime %{
10*67f94e5aSSiger Yang#ifdef __cplusplus
11*67f94e5aSSiger Yangextern "C" {
12*67f94e5aSSiger Yang#endif
13*67f94e5aSSiger Yang
14*67f94e5aSSiger Yangvoid LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton);
15*67f94e5aSSiger Yangint LLDBSwigLuaCloseFileHandle(lua_State *L);
16*67f94e5aSSiger Yang
17*67f94e5aSSiger Yang#ifdef __cplusplus
18*67f94e5aSSiger Yang}
19*67f94e5aSSiger Yang#endif
20*67f94e5aSSiger Yang%}
21*67f94e5aSSiger Yang
22a0d7406aSPedro Tammela%wrapper %{
23a0d7406aSPedro Tammela
24a0d7406aSPedro Tammela// This function is called from Lua::CallBreakpointCallback
25a0d7406aSPedro TammelaSWIGEXPORT llvm::Expected<bool>
26a0d7406aSPedro TammelaLLDBSwigLuaBreakpointCallbackFunction
27a0d7406aSPedro Tammela(
28a0d7406aSPedro Tammela   lua_State *L,
29a0d7406aSPedro Tammela   lldb::StackFrameSP stop_frame_sp,
30532e4203SPedro Tammela   lldb::BreakpointLocationSP bp_loc_sp,
31532e4203SPedro Tammela   StructuredDataImpl *extra_args_impl
32a0d7406aSPedro Tammela)
33a0d7406aSPedro Tammela{
34a0d7406aSPedro Tammela   lldb::SBFrame sb_frame(stop_frame_sp);
35a0d7406aSPedro Tammela   lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
36532e4203SPedro Tammela   int nargs = 2;
37532e4203SPedro Tammela
38532e4203SPedro Tammela   llvm::Optional<lldb::SBStructuredData> extra_args;
39532e4203SPedro Tammela   if (extra_args_impl)
40532e4203SPedro Tammela      extra_args = lldb::SBStructuredData(extra_args_impl);
41a0d7406aSPedro Tammela
42a0d7406aSPedro Tammela   // Push the Lua wrappers
43a0d7406aSPedro Tammela   PushSBClass(L, &sb_frame);
44a0d7406aSPedro Tammela   PushSBClass(L, &sb_bp_loc);
45a0d7406aSPedro Tammela
46532e4203SPedro Tammela   if (extra_args.hasValue()) {
47532e4203SPedro Tammela      PushSBClass(L, extra_args.getPointer());
48532e4203SPedro Tammela      nargs++;
49532e4203SPedro Tammela   }
50532e4203SPedro Tammela
51a0d7406aSPedro Tammela   // Call into the Lua callback passing 'sb_frame' and 'sb_bp_loc'.
52a0d7406aSPedro Tammela   // Expects a boolean return.
53532e4203SPedro Tammela   if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
54a0d7406aSPedro Tammela      llvm::Error E = llvm::make_error<llvm::StringError>(
55a0d7406aSPedro Tammela            llvm::formatv("{0}\n", lua_tostring(L, -1)),
56a0d7406aSPedro Tammela            llvm::inconvertibleErrorCode());
57a0d7406aSPedro Tammela      // Pop error message from the stack.
58a0d7406aSPedro Tammela      lua_pop(L, 1);
59a0d7406aSPedro Tammela      return std::move(E);
60a0d7406aSPedro Tammela   }
61a0d7406aSPedro Tammela
62a0d7406aSPedro Tammela   // Boolean return from the callback
63a0d7406aSPedro Tammela   bool stop = lua_toboolean(L, -1);
64a0d7406aSPedro Tammela   lua_pop(L, 1);
65a0d7406aSPedro Tammela
66a0d7406aSPedro Tammela   return stop;
67a0d7406aSPedro Tammela}
68a0d7406aSPedro Tammela
69e81ba283SSiger Yang// This function is called from Lua::CallWatchpointCallback
70e81ba283SSiger YangSWIGEXPORT llvm::Expected<bool>
71e81ba283SSiger YangLLDBSwigLuaWatchpointCallbackFunction
72e81ba283SSiger Yang(
73e81ba283SSiger Yang   lua_State *L,
74e81ba283SSiger Yang   lldb::StackFrameSP stop_frame_sp,
75e81ba283SSiger Yang   lldb::WatchpointSP wp_sp
76e81ba283SSiger Yang)
77e81ba283SSiger Yang{
78e81ba283SSiger Yang   lldb::SBFrame sb_frame(stop_frame_sp);
79e81ba283SSiger Yang   lldb::SBWatchpoint sb_wp(wp_sp);
80e81ba283SSiger Yang   int nargs = 2;
81e81ba283SSiger Yang
82e81ba283SSiger Yang   // Push the Lua wrappers
83e81ba283SSiger Yang   PushSBClass(L, &sb_frame);
84e81ba283SSiger Yang   PushSBClass(L, &sb_wp);
85e81ba283SSiger Yang
86e81ba283SSiger Yang   // Call into the Lua callback passing 'sb_frame' and 'sb_wp'.
87e81ba283SSiger Yang   // Expects a boolean return.
88e81ba283SSiger Yang   if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
89e81ba283SSiger Yang      llvm::Error E = llvm::make_error<llvm::StringError>(
90e81ba283SSiger Yang            llvm::formatv("{0}\n", lua_tostring(L, -1)),
91e81ba283SSiger Yang            llvm::inconvertibleErrorCode());
92e81ba283SSiger Yang      // Pop error message from the stack.
93e81ba283SSiger Yang      lua_pop(L, 1);
94e81ba283SSiger Yang      return std::move(E);
95e81ba283SSiger Yang   }
96e81ba283SSiger Yang
97e81ba283SSiger Yang   // Boolean return from the callback
98e81ba283SSiger Yang   bool stop = lua_toboolean(L, -1);
99e81ba283SSiger Yang   lua_pop(L, 1);
100e81ba283SSiger Yang
101e81ba283SSiger Yang   return stop;
102e81ba283SSiger Yang}
103e81ba283SSiger Yang
104*67f94e5aSSiger YangSWIGEXPORT void
105*67f94e5aSSiger YangLLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton) {
106*67f94e5aSSiger Yang   lua_State *L = (lua_State *)baton;
107*67f94e5aSSiger Yang
108*67f94e5aSSiger Yang   lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
109*67f94e5aSSiger Yang   lua_gettable(L, LUA_REGISTRYINDEX);
110*67f94e5aSSiger Yang
111*67f94e5aSSiger Yang   // FIXME: There's no way to report errors back to the user
112*67f94e5aSSiger Yang   lua_pushstring(L, str);
113*67f94e5aSSiger Yang   lua_pcall(L, 1, 0, 0);
114*67f94e5aSSiger Yang}
115*67f94e5aSSiger Yang
116*67f94e5aSSiger Yangint LLDBSwigLuaCloseFileHandle(lua_State *L) {
117*67f94e5aSSiger Yang   return luaL_error(L, "You cannot close a file handle used by lldb.");
118*67f94e5aSSiger Yang}
119a0d7406aSPedro Tammela
120a0d7406aSPedro Tammela%}
121