1if not modules then modules = { } end modules ['luat-sto'] = {
2 version = 1.001,
3 comment = "companion to luat-lib.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11local type, next, setmetatable, getmetatable, collectgarbage = type, next, setmetatable, getmetatable, collectgarbage
12local gmatch, format = string.gmatch, string.format
13local serialize, concat, sortedhash = table.serialize, table.concat, table.sortedhash
14local setbytecode = lua.setbytecode
15local strippedloadstring = utilities.lua.strippedloadstring
16local loadstring = utilities.lua.loadstring
17local formatters = string.formatters
18
19local trace_storage = false
20local report_storage = logs.reporter("system","storage")
21
22storage = storage or { }
23local storage = storage
24
25local data = { }
26storage.data = data
27
28storage.min = 0
29storage.max = storage.min - 1
30storage.noftables = storage.noftables or 0
31storage.nofmodules = storage.nofmodules or 0
32
33storage.mark = utilities.storage.mark
34storage.allocate = utilities.storage.allocate
35storage.marked = utilities.storage.marked
36storage.strip = false
37
38directives.register("system.compile.strip", function(v) storage.strip = v end)
39
40function storage.register(...)
41 local t = { ... }
42 local d = t[2]
43 if d then
44 storage.mark(d)
45 else
46 report_storage("fatal error: invalid storage %a",t[1])
47 os.exit()
48 end
49 data[#data+1] = t
50 return t
51end
52
53local n = 0
54
55if environment.initex then
56
57 local function dump()
58 local max = storage.max
59 local strip = storage.strip
60 for i=1,#data do
61 max = max + 1
62 local tabledata = data[i]
63 local message = tabledata[1]
64 local original = tabledata[2]
65 local target = tabledata[3]
66 local definition = utilities.tables.definetable(target,false,true)
67 local comment = formatters["restoring %s from slot %s"](message,max)
68 if trace_storage then
69 comment = formatters["print('%s')"](comment)
70 else
71 comment = formatters["-- %s"](comment)
72 end
73 local dumped = serialize(original,target)
74 if trace_storage then
75 report_storage("saving %a in slot %a, size %s",message,max,#dumped)
76 end
77
78 dumped = concat({ definition, comment, dumped },"\n")
79 local code = nil
80 local name = formatters["slot %s (%s)"](max,name)
81 if LUAVERSION >= 5.3 then
82 local code = loadstring(dumped,name)
83 setbytecode(max,code,strip)
84 else
85 local code = strippedloadstring(dumped,name,strip)
86 setbytecode(max,code)
87 end
88 collectgarbage("step")
89 end
90 storage.max = max
91 end
92
93 lua.registerinitexfinalizer(dump,"dump storage")
94
95end
96
97statistics.register("stored bytecode data", function()
98 local nofbytecodes = CONTEXTLMTXMODE > 0 and status.luastate.bytecodes or status.luabytecodes
99 local nofmodules = (storage.nofmodules > 0 and storage.nofmodules) or (nofbytecodes - lua.firstbytecode - 1)
100 local nofdumps = (storage.noftables > 0 and storage.noftables ) or storage.max-storage.min + 1
101 local tofmodules = storage.tofmodules or 0
102 local tofdumps = storage.toftables or 0
103 if environment.initex then
104 local luautilities = utilities.lua
105 return format("%s modules, %s tables, %s chunks, %s chunks stripped (%s bytes)",
106 nofmodules,
107 nofdumps,
108 nofmodules + nofdumps,
109 luautilities.nofstrippedchunks or 0,
110 luautilities.nofstrippedbytes or 0
111 )
112 else
113 return format("%s modules (%0.3f sec), %s tables (%0.3f sec), %s chunks (%0.3f sec)",
114 nofmodules, tofmodules,
115 nofdumps, tofdumps,
116 nofmodules + nofdumps, tofmodules + tofdumps
117 )
118 end
119end)
120
121if lua.bytedata then
122 storage.register("lua/bytedata",lua.bytedata,"lua.bytedata")
123end
124
125
126
127
128storage.shared = storage.shared or { }
129
130storage.register("storage/shared", storage.shared, "storage.shared")
131
132local mark = storage.mark
133
134if string.patterns then mark(string.patterns) end
135if string.formatters then mark(string.formatters) end
136if lpeg.patterns then mark(lpeg.patterns) end
137if os.env then mark(os.env) end
138if number.dimenfactors then mark(number.dimenfactors) end
139if libraries then for k,v in next, libraries do mark(v) end end
140 |