1NRE(3) Tcl Library Procedures NRE(3)
2
3
4
5______________________________________________________________________________
6
8 Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv,
9 Tcl_NRCmdSwap, Tcl_NRExprObj, Tcl_NRAddCallback - Non-Recursive (stack‐
10 less) evaluation of Tcl scripts.
11
13 #include <tcl.h>
14
15 Tcl_Command
16 Tcl_NRCreateCommand(interp, cmdName, proc, nreProc, clientData,
17 deleteProc)
18
19 int
20 Tcl_NRCallObjProc(interp, nreProc, clientData, objc, objv)
21
22 int
23 Tcl_NREvalObj(interp, objPtr, flags)
24
25 int
26 Tcl_NREvalObjv(interp, objc, objv, flags)
27
28 int
29 Tcl_NRCmdSwap(interp, cmd, objc, objv, flags)
30
31 int
32 Tcl_NRExprObj(interp, objPtr, resultPtr)
33
34 void
35 Tcl_NRAddCallback(interp, postProcPtr, data0, data1, data2, data3)
36
38 Tcl_Interp *interp (in) Interpreter in which to create
39 or evaluate a command.
40
41 char *cmdName (in) Name of a new command to cre‐
42 ate.
43
44 Tcl_ObjCmdProc *proc (in) Implementation of a command
45 that will be called whenever
46 cmdName is invoked as a command
47 in the unoptimized way.
48
49 Tcl_ObjCmdProc *nreProc (in) Implementation of a command
50 that will be called whenever
51 cmdName is invoked and
52 requested to conserve the C
53 stack.
54
55 ClientData clientData (in) Arbitrary one-word value that
56 will be passed to proc, nre‐
57 Proc, deleteProc and objProc.
58
59 Tcl_CmdDeleteProc *deleteProc (in/out) Procedure to call before cmd‐
60 Name is deleted from the inter‐
61 preter. This procedure allows
62 for command-specific cleanup.
63 If deleteProc is NULL, then no
64 procedure is called before the
65 command is deleted.
66
67 int objc (in) Count of parameters provided to
68 the implementation of a com‐
69 mand.
70
71 Tcl_Obj **objv (in) Pointer to an array of Tcl val‐
72 ues. Each value holds the value
73 of a single word in the command
74 to execute.
75
76 Tcl_Obj *objPtr (in) Pointer to a Tcl_Obj whose
77 value is a script or expression
78 to execute.
79
80 int flags (in) ORed combination of flag bits
81 that specify additional
82 options. TCL_EVAL_GLOBAL is
83 the only flag that is currently
84 supported.
85
86 Tcl_Command cmd (in) Token for a command that is to
87 be used instead of the cur‐
88 rently executing command.
89
90 Tcl_Obj *resultPtr (out) Pointer to an unshared Tcl_Obj
91 where the result of expression
92 evaluation is written.
93
94 Tcl_NRPostProc *postProcPtr (in) Pointer to a function that will
95 be invoked when the command
96 currently executing in the
97 interpreter designated by
98 interp completes.
99
100 ClientData data0 (in)
101
102 ClientData data1 (in)
103
104 ClientData data2 (in)
105
106 ClientData data3 (in) data0 through data3 are four
107 one-word values that will be
108 passed to the function desig‐
109 nated by postProcPtr when it is
110 invoked.
111______________________________________________________________________________
112
114 This series of C functions provides an interface whereby commands that
115 are implemented in C can be evaluated, and invoke Tcl commands scripts
116 and scripts, without consuming space on the C stack. The non-recursive
117 evaluation is done by installing a trampoline, a small piece of code
118 that invokes a command or script, and then executes a series of call‐
119 backs when the command or script returns.
120
121 The Tcl_NRCreateCommand function creates a Tcl command in the inter‐
122 preter designated by interp that is prepared to handle nonrecursive
123 evaluation with a trampoline. The cmdName argument gives the name of
124 the new command. If cmdName contains any namespace qualifiers, then the
125 new command is added to the specified namespace; otherwise, it is added
126 to the global namespace. proc gives the procedure that will be called
127 when the interpreter wishes to evaluate the command in an unoptimized
128 manner, and nreProc is the procedure that will be called when the
129 interpreter wishes to evaluate the command using a trampoline.
130 deleteProc is a function that will be called before the command is
131 deleted from the interpreter. When any of the three functions is
132 invoked, it is passed the clientData parameter.
133
134 Tcl_NRCreateCommand deletes any existing command name already associ‐
135 ated with the interpreter (however see below for an exception where the
136 existing command is not deleted). It returns a token that may be used
137 to refer to the command in subsequent calls to Tcl_GetCommandName. If
138 Tcl_NRCreateCommand is called for an interpreter that is in the process
139 of being deleted, then it does not create a new command, does not
140 delete any existing command of the same name, and returns NULL.
141
142 The proc and nreProc function are expected to conform to all the rules
143 set forth for the proc argument to Tcl_CreateObjCommand(3) (q.v.).
144
145 When a command that is written to cope with evaluation via trampoline
146 is invoked without a trampoline on the stack, it will usually respond
147 to the invocation by creating a trampoline and calling the trampoline-
148 enabled implementation of the same command. This call is done by means
149 of Tcl_NRCallObjProc. In the call to Tcl_NRCallObjProc, the interp,
150 clientData, objc and objv parameters should be the same ones that were
151 passed to proc. The nreProc parameter should designate the trampoline-
152 enabled implementation of the command.
153
154 Tcl_NREvalObj arranges for the script contained in objPtr to be evalu‐
155 ated in the interpreter designated by interp after the current command
156 (which must be trampoline-enabled) returns. It is the method by which a
157 command may invoke a script without consuming space on the C stack.
158 Similarly, Tcl_NREvalObjv arranges to invoke a single Tcl command whose
159 words have already been separated and substituted. The objc and objv
160 parameters give the words of the command to be evaluated when execution
161 reaches the trampoline.
162
163 Tcl_NRCmdSwap allows for trampoline evaluation of a command whose reso‐
164 lution is already known. The cmd parameter gives a Tcl_Command token
165 (returned from Tcl_CreateObjCommand or Tcl_GetCommandFromObj) identify‐
166 ing the command to be invoked in the trampoline; this command must
167 match the word in objv[0]. The remaining arguments are as for
168 Tcl_NREvalObjv.
169
170 Tcl_NREvalObj, Tcl_NREvalObjv and Tcl_NRCmdSwap all accept a flags
171 parameter, which is an OR-ed-together set of bits to control evalua‐
172 tion. At the present time, the only supported flag available to callers
173 is TCL_EVAL_GLOBAL. If the TCL_EVAL_GLOBAL flag is set, the script or
174 command is evaluated in the global namespace. If it is not set, it is
175 evaluated in the current namespace.
176
177 Tcl_NRExprObj arranges for the expression contained in objPtr to be
178 evaluated in the interpreter designated by interp after the current
179 command (which must be trampoline-enabled) returns. It is the method by
180 which a command may evaluate a Tcl expression without consuming space
181 on the C stack. The argument resultPtr is a pointer to an unshared
182 Tcl_Obj where the result of expression evaluation is to be written. If
183 expression evaluation returns any code other than TCL_OK, the resultPtr
184 value is left untouched.
185
186 All of the routines return TCL_OK if command or expression invocation
187 has been scheduled successfully. If for any reason the scheduling can‐
188 not be completed (for example, if the interpreter is unable to find the
189 requested command), they return TCL_ERROR with an appropriate message
190 left in the interpreter's result.
191
192 Tcl_NRAddCallback arranges to have a C function called when the current
193 trampoline-enabled command in the Tcl interpreter designated by interp
194 returns. The postProcPtr argument is a pointer to the callback func‐
195 tion, which must have arguments and return value consistent with the
196 Tcl_NRPostProc data type:
197
198 typedef int
199 Tcl_NRPostProc(
200 ClientData data[],
201 Tcl_Interp *interp,
202 int result);
203
204 When the trampoline invokes the callback function, the data parameter
205 will point to an array containing the four one-word quantities that
206 were passed to Tcl_NRAddCallback in the data0 through data3 parameters.
207 The Tcl interpreter will be designated by the interp parameter, and the
208 result parameter will contain the result (TCL_OK, TCL_ERROR,
209 TCL_RETURN, TCL_BREAK or TCL_CONTINUE) that was returned by the command
210 evaluation. The callback function is expected, in turn, either to
211 return a result to control further evaluation.
212
213 Multiple Tcl_NRAddCallback invocations may request multiple callbacks,
214 which may be to the same or different callback functions. If multiple
215 callbacks are requested, they are executed in last-in, first-out order,
216 that is, the most recently requested callback is executed first.
217
219 The usual pattern for Tcl commands that invoke other Tcl commands is
220 something like:
221
222 int
223 TheCmdOldObjProc(
224 ClientData clientData,
225 Tcl_Interp *interp,
226 int objc,
227 Tcl_Obj *const objv[])
228 {
229 int result;
230 Tcl_Obj *objPtr;
231
232 ... preparation ...
233
234 result = Tcl_EvalObjEx(interp, objPtr, 0);
235
236 ... postprocessing ...
237
238 return result;
239 }
240 Tcl_CreateObjCommand(interp, "theCommand",
241 TheCmdOldObjProc, clientData, TheCmdDeleteProc);
242
243 To enable a command like this one for trampoline-based evaluation, it
244 must be split into three pieces:
245
246 · A non-trampoline implementation, TheCmdNewObjProc, which will
247 simply create a trampoline and invoke the trampoline-based
248 implementation.
249
250 · A trampoline-enabled implementation, TheCmdNRObjProc. This
251 function will perform the initialization, request that the tram‐
252 poline call the postprocessing routine after command evaluation,
253 and finally, request that the trampoline call the inner command.
254
255 · A postprocessing routine, TheCmdPostProc. This function will
256 perform the postprocessing formerly done after the return from
257 the inner command in TheCmdObjProc.
258
259 The non-trampoline implementation is simple and stylized, containing a
260 single statement:
261
262 int
263 TheCmdNewObjProc(
264 ClientData clientData,
265 Tcl_Interp *interp,
266 int objc,
267 Tcl_Obj *const objv[])
268 {
269 return Tcl_NRCallObjProc(interp, TheCmdNRObjProc,
270 clientData, objc, objv);
271 }
272
273 The trampoline-enabled implementation requests postprocessing, and
274 returns to the trampoline requesting command evaluation.
275
276 int
277 TheCmdNRObjProc
278 ClientData clientData,
279 Tcl_Interp *interp,
280 int objc,
281 Tcl_Obj *const objv[])
282 {
283 Tcl_Obj *objPtr;
284
285 ... preparation ...
286
287 Tcl_NRAddCallback(interp, TheCmdPostProc,
288 data0, data1, data2, data3);
289 /* data0 .. data3 are up to four one-word items to
290 * pass to the postprocessing procedure */
291
292 return Tcl_NREvalObj(interp, objPtr, 0);
293 }
294
295 The postprocessing procedure does whatever the original command did
296 upon return from the inner evaluation.
297
298 int
299 TheCmdNRPostProc(
300 ClientData data[],
301 Tcl_Interp *interp,
302 int result)
303 {
304 /* data[0] .. data[3] are the four words of data
305 * passed to Tcl_NRAddCallback */
306
307 ... postprocessing ...
308
309 return result;
310 }
311
312 If theCommand is a command that results in multiple commands or scripts
313 being evaluated, its postprocessing routine may schedule additional
314 postprocessing and then request another command evaluation by means of
315 Tcl_NREvalObj or one of the other evaluation routines. Looping and
316 sequencing constructs may be implemented in this way.
317
318 Finally, to install a trampoline-enabled command in the interpreter,
319 Tcl_NRCreateCommand is used in place of Tcl_CreateObjCommand. It
320 accepts two command procedures instead of one. The first is for use
321 when no trampoline is yet on the stack, and the second is for use when
322 there is already a trampoline in place.
323
324 Tcl_NRCreateCommand(interp, "theCommand",
325 TheCmdNewObjProc, TheCmdNRObjProc, clientData,
326 TheCmdDeleteProc);
327
329 Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3),
330 Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
331
333 stackless, nonrecursive, execute, command, global, value, result,
334 script
335
337 Copyright (c) 2008 by Kevin B. Kenny
338
339
340
341Tcl 8.6 NRE(3)