@@ -166,19 +166,71 @@ HANDLE Open_Luamacro(lua_State* L, const struct OpenInfo *Info)
166166typedef struct
167167{
168168 lua_State * L ;
169- int ret_avail ;
169+ int start_stack ;
170+ int max_stack ;
170171 int error ;
171172} mcfc_data ;
172173
173174static void WINAPI MacroCallFarCallback (void * Data , struct FarMacroValue * Val , size_t Count )
174175{
175176 mcfc_data * cbdata = (mcfc_data * )Data ;
177+ if (cbdata -> error )
178+ return ;
179+
176180 (void ) Count ;
177- if (!cbdata -> error && cbdata -> ret_avail > 0 )
181+ lua_State * L = cbdata -> L ;
182+ int top = lua_gettop (L );
183+ int stack_avail = cbdata -> max_stack - top ;
184+
185+ switch (Val -> Type )
178186 {
179- cbdata -> error = (Val -> Type == FMVT_ERROR );
180- cbdata -> ret_avail += (Val -> Type == FMVT_SETTABLE ) ? 2 : -1 ;
181- PushFarMacroValue (cbdata -> L , Val );
187+ case FMVT_NEWTABLE :
188+ if (stack_avail > 0 )
189+ lua_newtable (L );
190+ break ;
191+
192+ case FMVT_SETTABLE :
193+ if (lua_istable (L , -3 ))
194+ lua_settable (L , -3 );
195+ break ;
196+
197+ case FMVT_GETTABLE :
198+ if (stack_avail > 0 )
199+ {
200+ lua_gettable (L , -3 );
201+ ConvertLuaValue (L , -1 , Val );
202+ }
203+ break ;
204+
205+ case FMVT_STACKPOP :
206+ int param = (int )Val -> Value .Integer ;
207+ if (param > 0 && (top - param ) >= cbdata -> start_stack )
208+ lua_pop (L , param );
209+ break ;
210+
211+ case FMVT_STACKGETTOP :
212+ Val -> Type = FMVT_INTEGER ;
213+ Val -> Value .Integer = lua_gettop (L );
214+ break ;
215+
216+ case FMVT_STACKSETTOP :
217+ int val = (int )Val -> Value .Integer ;
218+ if (val >= cbdata -> start_stack && val <= cbdata -> max_stack )
219+ lua_settop (L , val );
220+ break ;
221+
222+ case FMVT_STACKPUSHVALUE :
223+ if (stack_avail > 0 )
224+ lua_pushvalue (L , (int )Val -> Value .Integer );
225+ break ;
226+
227+ default :
228+ if (stack_avail > 0 )
229+ {
230+ cbdata -> error = (Val -> Type == FMVT_ERROR );
231+ PushFarMacroValue (L , Val );
232+ }
233+ break ;
182234 }
183235}
184236
@@ -187,17 +239,18 @@ int far_MacroCallFar(lua_State *L)
187239 enum { MAXARG = 32 , MAXRET = 32 };
188240 struct FarMacroValue args [MAXARG ];
189241 struct FarMacroCall fmc ;
190- int idx , ret , pushed ;
191- mcfc_data cbdata = { L , MAXRET , 0 };
242+ int top = lua_gettop ( L ) ;
243+ mcfc_data cbdata = { L , top , top + MAXRET , 0 };
192244 TPluginData * pd = GetPluginData (L );
193245 struct MacroPrivateInfo * privateInfo = (struct MacroPrivateInfo * )pd -> Info -> Private ;
246+
194247 int opcode = (int )luaL_checkinteger (L , 1 );
195- fmc .Count = lua_gettop ( L ) - 1 ;
248+ fmc .Count = top - 1 ;
196249 fmc .Values = fmc .Count <=MAXARG ? args :(struct FarMacroValue * )malloc (fmc .Count * sizeof (struct FarMacroValue ));
197250 fmc .Callback = MacroCallFarCallback ;
198251 fmc .CallbackData = & cbdata ;
199252
200- for (idx = 0 ; idx < (int )fmc .Count ; idx ++ )
253+ for (int idx = 0 ; idx < (int )fmc .Count ; idx ++ )
201254 {
202255 ConvertLuaValue (L , idx + 2 , fmc .Values + idx );
203256 if (fmc .Values [idx ].Type == FMVT_UNKNOWN )
@@ -213,9 +266,9 @@ int far_MacroCallFar(lua_State *L)
213266 }
214267
215268 lua_checkstack (L , MAXRET );
216- ret = (int ) privateInfo -> CallFar (opcode , & fmc );
269+ int ret = (int ) privateInfo -> CallFar (opcode , & fmc );
217270 FP_PROTECT (); // protect from plugins activating FPU exceptions
218- pushed = MAXRET - cbdata . ret_avail ;
271+ int pushed = lua_gettop ( L ) - top ;
219272 if (fmc .Values != args )
220273 free (fmc .Values );
221274 if (cbdata .error )
0 commit comments