summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/luat-cod.mkiv
blob: d3b37d0e1458ca4b1a501a7a707a603e0e561e59 (plain)
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
%D \module
%D   [       file=luat-cod,
%D        version=2005.05.26,
%D          title=\CONTEXT\ Lua Macros,
%D       subtitle=Code,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright=PRAGMA]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

% \writestatus{loading}{ConTeXt Lua Macros / Code}

%D Originally we compiled the lua files externally and loaded
%D then at runtime, but when the amount grew, we realized that
%D we needed away to store them in the format, which is what
%D bytecode arrays do. And so the following is obsolete:
%D
%D \starttyping
%D \chardef\ctxluaembeddingmode \plusone
%D
%D 0 = external compilation and loading
%D 1 = runtime compilation and embedding
%D \stoptyping
%D
%D Allocation of \LUA\ engines has changed too. The original idea
%D was to have multiple \LUA\ instances and it worked that way for
%D several years. Hoewver in practice we used only one engine because
%D scripts need to share data anyway. So eventually \LUATEX\ got only
%D one instance. Because each call is reentrant there is not much
%D danger for crashes.

\def\ctxdirectlua{\directlua\zerocount}
\def\ctxlatelua  {\latelua  \zerocount}

%D Take your choice \unknown

\let\ctxlua       \ctxdirectlua
\let\luacode      \ctxdirectlua
\let\lateluacode  \ctxlatelua
\let\directluacode\ctxdirectlua

%D Reporting the version of \LUA\ that we use is done as follows:

\edef\luaversion{\ctxlua{tex.print(_VERSION)}}

%D We want to define \LUA\ related things in the format but
%D need to reload code because \LUA\ instances themselves are
%D not dumped into the format.

\newtoks\everyloadluacode
\newtoks\everyfinalizeluacode

\normaleveryjob{\the\everyloadluacode\the\everyfinalizeluacode\the\everyjob}

\newif\ifproductionrun

%D Here we operate in the \TEX\ catcode regime as we haven't yet defined
%D catcode regimes. A chicken or egg problem.

\normalprotected\long\def\startruntimeluacode#1\stopruntimeluacode % only simple code (load +init)
  {\ifproductionrun
     \global\let\startruntimeluacode\relax
     \global\let\stopruntimeluacode \relax
   \else
     \global\everyloadluacode\expandafter{\the\everyloadluacode#1}%
   \fi
   #1} % maybe no interference

\normalprotected\long\def\startruntimectxluacode#1\stopruntimectxluacode
  {\startruntimeluacode\ctxlua{#1}\stopruntimeluacode}

%D Next we load the initialization code.

\startruntimectxluacode
    environment = environment or { }
    environment.jobname = "\jobname"                            % tex.jobname
    environment.initex  = \ifproductionrun false \else true \fi % tex.formatname == ""
    environment.version = "\fmtversion"
\stopruntimectxluacode

% we start at 500, below this, we store predefined data (dumps)

\newcount\luabytecodecounter \luabytecodecounter=500

\startruntimectxluacode
    lua.bytedata = lua.bytedata or { }
\stopruntimectxluacode

%D Handy when we expand:

\let\stopruntimeluacode   \relax
\let\stopruntimectxluacode\relax

\long\def\lastexpanded{} % todo: elsewhere we use \@@expanded

\long\def\expanded#1{\long\xdef\lastexpanded{\noexpand#1}\lastexpanded}

%D More code:

% \def\ctxluabytecode#1% executes an already loaded chunk
%   {\ctxlua {
%       local str = ''
%       if lua.bytedata[#1] then
%           str = " from file " .. lua.bytedata[#1][1] .. " version " .. lua.bytedata[#1][2]
%       end
%       if lua.bytecode[#1] then
%           if environment.initex then
%               texio.write_nl("bytecode: executing blob " .. "#1" .. str)
%               assert(lua.bytecode[#1])()
%           else
%               texio.write_nl("bytecode: initializing blob " .. "#1" .. str)
%               assert(lua.bytecode[#1])()
%               lua.bytecode[#1] = nil
%           end
%       else
%          texio.write_nl("bytecode: invalid blob " .. "#1" .. str)
%       end
%   }}

\def\ctxluabytecode#1% executes an already loaded chunk
  {\ctxlua {
      local lbc = lua.bytecode
      if lbc[#1] then
          assert(lbc[#1])()
          if not environment.initex then
              lbc[#1] = nil
          end
      end
  }}

\def\ctxluabyteload#1#2% registers and compiles chunk
  {\global\advance\luabytecodecounter \plusone
   \normalexpanded{\startruntimectxluacode
     lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" }
   \stopruntimectxluacode}%
   \ctxlua {
     lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" }
     lua.bytecode[\the\luabytecodecounter] = environment.luafilechunk("#1")
    }}

\def\ctxloadluafile#1#2% load a (either not compiled) chunk at runtime
  {\doifelsenothing{#2}
     {\ctxlua{environment.loadluafile("#1")}}
     {\ctxlua{environment.loadluafile("#1",#2)}}}

\def\registerctxluafile#1#2% name version (modules and core code)
  {\ifproductionrun
     \ctxloadluafile{#1}{#2}%
   \else
     \ctxluabyteload{#1}{#2}% can go away
   \fi
   \global\everyloadluacode\expandafter\expandafter\expandafter{\expandafter\the\expandafter\everyloadluacode
      \expandafter\ctxluabytecode\expandafter{\the\luabytecodecounter}}%
   \ctxluabytecode{\the\luabytecodecounter}}

\everydump\expandafter{\the\everydump\ctxlua{luatex.dumpstate(environment.jobname..".lui",501)}}

\endinput