-
Notifications
You must be signed in to change notification settings - Fork 1
/
LuaHost.inc
181 lines (145 loc) · 5.92 KB
/
LuaHost.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
; ==================================================================================================
; Title: LuaHost.inc
; Author: G. Friedrich
; Version: C.1.0
; Purpose: ObjAsm support of Lua Host objects.
; Notes: Version C.1.0, November 2023
; - First release.
; ==================================================================================================
;Lua Host Messages we use to communicate with the main application
LHM_SCRIPT_FINISHED equ WM_USER + 10
; ——————————————————————————————————————————————————————————————————————————————————————————————————
; Object: LuaHost
; Purpose: Implement a host container object for the Lua engine.
; Links: https://www.lua.org/
; Notes: - The Lua engine runs in its own thread, which is started with the Start method.
; This allows the engine to be used without freezing the GUI.
Object LuaHost, LuaHostID, Streamable
RedefineMethod Done
VirtualMethod Run
VirtualMethod Start, PSTRINGA
VirtualMethod Stop
DynamicMethod ScriptInit, Plua_State
DefineVariable hThread, HANDLE, 0
DefineVariable dFlags, DWORD, 0
DefineVariable pScript, PSTRINGA, NULL
ObjectEnd
; ==================================================================================================
if IMPLEMENT
;Lua Host Flags
LHF_SCRIPT_STOP equ BIT00
; ==================================================================================================
; LuaHost implementation
; ==================================================================================================
; ——————————————————————————————————————————————————————————————————————————————————————————————————
; Method: lua_HookProc
; Purpose: Control Lua instruction flow to implement a "Stop" function.
; Arguments: Arg1: -> lua_State
; Arg2: -> lua_Debug
; Return: eax = Number of arguments passed on the lua stack.
lua_HookProc proc uses xbx pLuaState:ptr lua_State, plua_Debug:ptr lua_Debug
; ?mov edx, plua_Debug
; DbgDec [xdx].lua_Debug.currentline
invoke lua_getglobal, pLuaState, $OfsCStrA("pLuaHost") ;Retrieve -> LuaHost
invoke lua_tointegerx, pLuaState, -1, NULL
.ifBitSet [xax].$Obj(LuaHost).dFlags, LHF_SCRIPT_STOP
invoke lua_pushstring, pLuaState, $OfsCStrA("STOP")
invoke lua_error, pLuaState
.endif
xor eax, eax
ret
lua_HookProc endp
; ——————————————————————————————————————————————————————————————————————————————————————————————————
; Method: LuaHost.Done
; Purpose: Finalize the Script engine object.
; Arguments: None.
; Return: Nothing.
Method LuaHost.Done, uses xsi
DbgText "LuaHost.Done"
SetObject xsi
.if [xsi].hThread != 0
invoke WaitForSingleObject, [xsi].hThread, 4000 ;Wait max 4 secs
.if eax == WAIT_TIMEOUT
DbgWarning "Script thread was forced to terminate; some resources may not be released."
invoke TerminateThread, [xsi].hThread, -1
invoke CloseHandle, [xsi].hThread
.endif
.endif
ACall xsi.Done
MethodEnd
; ——————————————————————————————————————————————————————————————————————————————————————————————————
; Method: LuaHost.Run
; Purpose: Message Handler for LHM_SCRIPT_EXECUTE.
; Arguments: None.
; Return: eax = return value (Lua error code).
Method LuaHost.Run, uses xbx xsi
local pLuaState:ptr lua_State, dRetVal:DWORD
DbgText "LuaHost.Run"
SetObject xsi
mov dRetVal, LUA_OK
;Initialize Lua & load libraries
mov xbx, $invoke(luaL_newstate)
invoke luaL_openlibs, xbx
;Store a pointer to the LuaHost as a global variable
invoke lua_pushinteger, xbx, xsi
invoke lua_setglobal, xbx, $OfsCStrA("pLuaHost")
;Set the call hook
invoke lua_sethook, xbx, addr lua_HookProc, LUA_MASKLINE, 0
OCall xsi.ScriptInit, xbx
cmp eax, LUA_OK
jnz @@Error
;Load the script
invoke luaL_loadstring, xbx, [xsi].pScript
cmp eax, LUA_OK
jnz @@Error
;Execute the script
invoke lua_pcallk, xbx, 0, LUA_MULTRET, 0, 0, NULL
@@Error:
mov dRetVal, eax
;Housekeeping
invoke lua_close, xbx ;Run the garbage collector one last time
MemFree [xsi].pScript
m2z [xsi].pScript
;Inform the main Application that the script has finished and pass an result value
mov xax, [xsi].pOwner
invoke PostMessage, [xax].$Obj(WinPrimer).hWnd, LHM_SCRIPT_FINISHED, dRetVal, 0
invoke CloseHandle, [xsi].hThread ;Decrement HANDLE count to release hThrend
mov eax, dRetVal ; when terminated
MethodEnd
; ——————————————————————————————————————————————————————————————————————————————————————————————————
; Method: LuaHost.ScriptInit
; Purpose: Script custom initialization.
; Arguments: Arg1: -> lua_State.
; Return: eax = LUA_OK if succeeded, otherwise an error code.
Method LuaHost.ScriptInit,, plua_State:Plua_State
DbgText "LuaHost.ScriptInit"
mov eax, LUA_OK
MethodEnd
; ——————————————————————————————————————————————————————————————————————————————————————————————————
; Method: LuaHost.Start
; Purpose: Start script execution.
; Arguments: Arg1: -> ANSI string containing the script to execute.
; Return: eax = TRUE if succeeded, otherwise FALSE.
Method LuaHost.Start, uses xsi, pScript:PSTRINGA
DbgText "LuaHost.Start"
SetObject xsi
m2m [xsi].pScript, pScript, xax
invoke CreateThread, NULL, 0, $MethodAddr(xsi::LuaHost.Run), xsi, CREATE_SUSPENDED, NULL
.if xax != 0
mov [xsi].hThread, xax
mov [xsi].dFlags, 0 ;Reset all other flags
invoke ResumeThread, xax
mov eax, TRUE
.endif
MethodEnd
; ——————————————————————————————————————————————————————————————————————————————————————————————————
; Method: LuaHost.Stop
; Purpose: Stop script execution.
; Arguments: None.
; Return: Nothing.
Method LuaHost.Stop
DbgText "LuaHost.Stop"
SetObject xcx
BitSet [xcx].dFlags, LHF_SCRIPT_STOP
MethodEnd
endif