1if not modules then modules = { } end modules ['util-lua'] = {
2 version = 1.001,
3 comment = "companion to luat-lib.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 comment = "the strip code is written by Peter Cawley",
6 copyright = "PRAGMA ADE / ConTeXt Development Team",
7 license = "see context related readme files"
8}
9
10
11
12local rep, sub, byte, dump, format = string.rep, string.sub, string.byte, string.dump, string.format
13local load, loadfile, type, collectgarbage = load, loadfile, type, collectgarbage
14
15utilities = utilities or {}
16utilities.lua = utilities.lua or { }
17local luautilities = utilities.lua
18
19local report_lua = logs.reporter("system","lua")
20local report_mem = logs.reporter("system","lua memory")
21
22local tracestripping = false
23local tracememory = false
24luautilities.stripcode = true
25luautilities.alwaysstripcode = false
26luautilities.nofstrippedchunks = 0
27luautilities.nofstrippedbytes = 0
28local strippedchunks = { }
29luautilities.strippedchunks = strippedchunks
30
31if not LUATEXENGINE then
32
33 LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
34 JITSUPPORTED = LUATEXENGINE == "luajittex" or jit
35 CONTEXTLMTXMODE = CONTEXTLMTXMODE or (LUATEXENGINE == "luametatex" and 1) or 0
36end
37
38luautilities.suffixes = {
39 tma = "tma",
40 tmc = (CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 and "tmd") or (jit and "tmb") or "tmc",
41 lua = "lua",
42 lmt = "lmt",
43 luc = (CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 and "lud") or (jit and "lub") or "luc",
44 lui = "lui",
45 luv = "luv",
46 luj = "luj",
47 tua = "tua",
48
49 tuc = (CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 and "tud") or (jit and "tub") or "tuc",
50}
51
52
53
54local function register(name)
55 if tracestripping then
56 report_lua("stripped bytecode from %a",name or "unknown")
57 end
58 strippedchunks[#strippedchunks+1] = name
59 luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1
60end
61
62local function stupidcompile(luafile,lucfile,strip)
63 local code = io.loaddata(luafile)
64 if code and code ~= "" then
65 code = load(code)
66 if code then
67 code = dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
68 if code and code ~= "" then
69 register(name)
70 io.savedata(lucfile,code)
71 return true, 0
72 end
73 else
74 report_lua("fatal error %a in file %a",1,luafile)
75 end
76 else
77 report_lua("fatal error %a in file %a",2,luafile)
78 end
79 return false, 0
80end
81
82
83
84function luautilities.loadedluacode(fullname,forcestrip,name,macros)
85
86 name = name or fullname
87 if macros then
88 macros = lua.macros
89 end
90 local code, message
91 if macros then
92 code, message = macros.loaded(fullname,true,false)
93 else
94 code, message = loadfile(fullname)
95 end
96 if code then
97 code()
98 else
99 report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
100 code, message = loadfile(fullname)
101 end
102 if forcestrip and luautilities.stripcode then
103 if type(forcestrip) == "function" then
104 forcestrip = forcestrip(fullname)
105 end
106 if forcestrip or luautilities.alwaysstripcode then
107 register(name)
108 return load(dump(code,true)), 0
109 else
110 return code, 0
111 end
112 elseif luautilities.alwaysstripcode then
113 register(name)
114 return load(dump(code,true)), 0
115 else
116 return code, 0
117 end
118end
119
120function luautilities.strippedloadstring(code,name,forcestrip)
121 local code, message = load(code)
122 if not code then
123 report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
124 end
125 if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
126 register(name)
127 return load(dump(code,true)), 0
128 else
129 return code, 0
130 end
131end
132
133function luautilities.loadstring(code,name)
134 local code, message = load(code)
135 if not code then
136 report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
137 end
138 return code, 0
139end
140
141function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
142 report_lua("compiling %a into %a",luafile,lucfile)
143 os.remove(lucfile)
144 local done = stupidcompile(luafile,lucfile,strip ~= false)
145 if done then
146 report_lua("dumping %a into %a stripped",luafile,lucfile)
147 if cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
148 report_lua("removing %a",luafile)
149 os.remove(luafile)
150 end
151 end
152 return done
153end
154
155function luautilities.loadstripped(...)
156 local l = load(...)
157 if l then
158 return load(dump(l,true))
159 end
160end
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188local finalizers = { }
189
190setmetatable(finalizers, {
191 __gc = function(t)
192 for i=1,#t do
193 pcall(t[i])
194 end
195 end
196} )
197
198function luautilities.registerfinalizer(f)
199 finalizers[#finalizers+1] = f
200end
201
202function luautilities.checkmemory(previous,threshold,trace)
203 local current = collectgarbage("count")
204 if previous then
205 local checked = (threshold or 64)*1024
206 local delta = current - previous
207 if current - previous > checked then
208 collectgarbage("collect")
209 local afterwards = collectgarbage("count")
210 if trace or tracememory then
211 report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
212 previous/1024,current/1024,delta/1024,threshold,afterwards)
213 end
214 return afterwards
215 elseif trace or tracememory then
216 report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
217 previous/1024,current/1024,delta/1024,threshold)
218 end
219 end
220 return current
221end
222 |