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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
| General Operations
------------------
done
Finish ByteCode execution and return stktop (top stack item)
push1, LIT1
Push object at ByteCode objArray[op1]
push4, LIT4
Push object at ByteCode objArray[op4]
nop
Do nothing
pop
Pop the topmost stack object
dup
Duplicate the topmost stack object and push the result
over, UINT4
Duplicate the arg-th element from top of stack (TOS=0)
reverse, UINT4
Reverse the order of the arg elements at the top of stack
break
Abort closest enclosing loop; if none, return TCL_BREAK code.
continue
Skip to next iteration of closest enclosing loop; if none, return
TCL_CONTINUE code.
beginCatch4, UINT4
Record start of catch with the operand's exception index. Push the
current stack depth onto a special catch stack.
endCatch
End of last catch. Pop the bytecode interpreter's catch stack.
pushResult
Push the interpreter's object result onto the stack.
pushReturnCode
Push interpreter's return code (e.g. TCL_OK or TCL_ERROR) as a new
object onto the stack.
pushReturnOpts
Push the interpreter's return option dictionary as an object on the
stack.
returnStk
Compiled [return]; options and result are on the stack, code and
level are in the options.
returnImm, INT4, UINT4
Compiled [return], code, level are operands; options and result
are on the stack.
syntax, INT4, UINT4
Compiled bytecodes to signal syntax error. Equivalent to returnImm
except for the ERR_ALREADY_LOGGED flag in the interpreter.
Jump Operations
---------------
jump1, OFFSET1
Jump relative to (pc + op1)
jump4, OFFSET4
Jump relative to (pc + op4)
jumpTrue1, OFFSET1
Jump relative to (pc + op1) if stktop expr object is true
jumpTrue4, OFFSET4
Jump relative to (pc + op4) if stktop expr object is true
jumpFalse1, OFFSET1
Jump relative to (pc + op1) if stktop expr object is false
jumpFalse4, OFFSET4
Jump relative to (pc + op4) if stktop expr object is false
startCommand, OFFSET4, UINT4
Start of bytecoded command: op is the length of the cmd's code, op2
is number of commands here
jumpTable, AUX4
Jump according to the jump-table (in AuxData as indicated by the
operand) and the argument popped from the list. Always executes the
next instruction if no match against the table's entries was found.
Stack: ... value => ...
Note that the jump table contains offsets relative to the PC when
it points to this instruction; the code is relocatable.
returnCodeBranch
Jump to next instruction based on the return code on top of stack
ERROR: +1; RETURN: +3; BREAK: +5; CONTINUE: +7;
Other non-OK: +9
String Operations
-----------------
strcat, UINT1
Concatenate the top op1 items and push result
streq
Str Equal: push (stknext eq stktop)
strneq
Str !Equal: push (stknext neq stktop)
strcmp
Str Compare: push (stknext cmp stktop)
strlen
Str Length: push (strlen stktop)
strindex
Str Index: push (strindex stknext stktop)
strmatch, INT1
Str Match: push (strmatch stknext stktop) opnd == nocase
strmap
Simplified version of [string map] that only applies one change
string, and only case-sensitively.
Stack: ... from to string => ... changedString
strfind
Find the first index of a needle string in a haystack string,
producing the index (integer) or -1 if nothing found.
Stack: ... needle haystack => ... index
strrfind
Find the last index of a needle string in a haystack string,
producing the index (integer) or -1 if nothing found.
Stack: ... needle haystack => ... index
strrangeImm, IDX4, IDX4
String Range: push (string range stktop op4 op4)
strrange
String Range with non-constant arguments.
Stack: ... string idxA idxB => ... substring
strtrim
[string trim] core: removes the characters (designated by the value
at the top of the stack) from both ends of the string and pushes
the resulting string.
Stack: ... string charset => ... trimmedString
strtrimLeft
[string trimleft] core: removes the characters (designated by the
value at the top of the stack) from the left of the string and
pushes the resulting string.
Stack: ... string charset => ... trimmedString
strtrimRight
[string trimright] core: removes the characters (designated by the
value at the top of the stack) from the right of the string and
pushes the resulting string.
Stack: ... string charset => ... trimmedString
strcaseUpper
[string toupper] core: converts whole string to upper case using
the default (extended "C" locale) rules.
Stack: ... string => ... newString
strcaseLower
[string tolower] core: converts whole string to upper case using
the default (extended "C" locale) rules.
Stack: ... string => ... newString
strcaseTitle
[string totitle] core: converts whole string to upper case using
the default (extended "C" locale) rules.
Stack: ... string => ... newString
strreplace
[string replace] core: replaces a non-empty range of one string
with the contents of another.
Stack: ... string fromIdx toIdx replacement => ... newString
strclass, SCLS1
See if all the characters of the given string are a member of the
specified (by opnd) character class. Note that an empty string will
satisfy the class check (standard definition of "all").
Stack: ... stringValue => ... boolean
regexp, INT1
Regexp: push (regexp stknext stktop) opnd == nocase
Invoke/Eval Operations
----------------------
evalStk
Evaluate command in stktop using Tcl_EvalObj.
exprStk
Execute expression in stktop using Tcl_ExprStringObj.
invokeStk1, UINT1
Invoke command named objv[0]; <objc,objv> = <op1,top op1>
invokeStk4, UINT4
Invoke command named objv[0]; <objc,objv> = <op4,top op4>
invokeReplace, UINT4,UINT1
Invoke command named objv[0], replacing the first two words with
the word at the top of the stack;
<objc,objv> = <op4,top op4 after popping 1>
callBuiltinFunc1, UINT1
Call builtin math function with index op1; any args are on stk.
OBSOLETE!
callFunc1, UINT1
Call non-builtin func objv[0]; <objc,objv>=<op1,top op1>
OBSOLETE!
Expansion Operations
--------------------
NOTE: the stack effects of expandStkTop and invokeExpanded are wrong -
but it cannot be done right at compile time, the stack effect is only
known at run time. The value for invokeExpanded is estimated better at
compile time.
See the comments in tclCompile.c, where INST_INVOKE_EXPANDED is emitted.
expandStart
Start of command with {*} (expanded) arguments
expandStkTop, UINT4
Expand the list at stacktop: push its elements on the stack
invokeExpanded
Invoke the command marked by the last 'expandStart'
expandDrop
Drops an element from the auxiliary stack, popping stack elements
until the matching stack depth is reached.
Variable Read Operations
------------------------
loadScalar1, LVT1
Load scalar variable at index op1 <= 255 in call frame
loadScalar4, LVT4
Load scalar variable at index op1 >= 256 in call frame
loadScalarStk
Load scalar variable; scalar's name is stktop
loadArray1, LVT1
Load array element; array at slot op1<=255, element is stktop
loadArray4, LVT4
Load array element; array at slot op1 > 255, element is stktop
loadArrayStk
Load array element; element is stktop, array name is stknext
loadStk
Load general variable; unparsed variable name is stktop
Variable Write Operations
-------------------------
storeScalar1, LVT1
Store scalar variable at op1<=255 in frame; value is stktop
storeScalar4, LVT4
Store scalar variable at op1 > 255 in frame; value is stktop
storeScalarStk
Store scalar; value is stktop, scalar name is stknext
storeArray1, LVT1
Store array element; array at op1<=255, value is top then elem
storeArray4, LVT4
Store array element; array at op1>=256, value is top then elem
storeArrayStk
Store array element; value is stktop, then elem, array names
storeStk
Store general variable; value is stktop, then unparsed name
Variable Increment Operations
-----------------------------
incrScalar1, LVT1
Incr scalar at index op1<=255 in frame; incr amount is stktop
incrScalarStk
Incr scalar; incr amount is stktop, scalar's name is stknext
incrArray1, LVT1
Incr array elem; arr at slot op1<=255, amount is top then elem
incrArrayStk
Incr array element; amount is top then elem then array names
incrStk
Incr general variable; amount is stktop then unparsed var name
incrScalar1Imm, LVT1, INT1
Incr scalar at slot op1 <= 255; amount is 2nd operand byte
incrScalarStkImm, INT1
Incr scalar; scalar name is stktop; incr amount is op1
incrArray1Imm, LVT1, INT1
Incr array elem; array at slot op1 <= 255, elem is stktop,
amount is 2nd operand byte
incrArrayStkImm, INT1
Incr array element; elem is top then array name, amount is op1
incrStkImm, INT1
Incr general variable; unparsed name is top, amount is op1
Variable Append Operations
--------------------------
appendScalar1, LVT1
Append scalar variable at op1<=255 in frame; value is stktop
appendScalar4, LVT4
Append scalar variable at op1 > 255 in frame; value is stktop
appendArray1, LVT1
Append array element; array at op1<=255, value is top then elem
appendArray4, LVT4
Append array element; array at op1>=256, value is top then elem
appendArrayStk
Append array element; value is stktop, then elem, array names
appendStk
Append general variable; value is stktop, then unparsed name
Math Operations
---------------
lor
Logical or: push (stknext || stktop)
land
Logical and: push (stknext && stktop)
bitor
Bitwise or: push (stknext | stktop)
bitxor
Bitwise xor push (stknext ^ stktop)
bitand
Bitwise and: push (stknext & stktop)
eq
Equal: push (stknext == stktop)
neq
Not equal: push (stknext != stktop)
lt
Less: push (stknext < stktop)
gt
Greater: push (stknext > stktop)
le
Less or equal: push (stknext <= stktop)
ge
Greater or equal: push (stknext >= stktop)
lshift
Left shift: push (stknext << stktop)
rshift
Right shift: push (stknext >> stktop)
add
Add: push (stknext + stktop)
sub
Sub: push (stkext - stktop)
mult
Multiply: push (stknext * stktop)
div
Divide: push (stknext / stktop)
mod
Mod: push (stknext % stktop)
expon
Binary exponentiation operator: push (stknext ** stktop)
uplus
Unary plus: push +stktop
uminus
Unary minus: push -stktop
bitnot
Bitwise not: push ~stktop
not
Logical not: push !stktop
tryCvtToNumeric
Try converting stktop to first int then double if possible.
numericType
Pushes the numeric type code of the word at the top of the stack.
Stack: ... value => ... typeCode
tryCvtToBoolean
Try converting stktop to boolean if possible. No errors.
Stack: ... value => ... value isStrictBool
List Iteration Operations
-------------------------
foreach_start4, AUX4
Initialize execution of a foreach loop. Operand is aux data index
of the ForeachInfo structure for the foreach command.
OBSOLETE!
foreach_step4, AUX4
"Step" or begin next iteration of foreach loop. Push 0 if to
terminate loop, else push 1.
OBSOLETE!
foreach_start, AUX4
Initialize execution of a foreach loop. Operand is aux data index
of the ForeachInfo structure for the foreach command. It pushes 2
elements which hold runtime params for foreach_step, they are later
dropped by foreach_end together with the value lists. NOTE that the
iterator-tracker and info reference must not be passed to bytecodes
that handle normal Tcl values. NOTE that this instruction jumps to
the foreach_step instruction paired with it; the stack info below
is only nominal.
Stack: ... listObjs... => ... listObjs... iterTracker info
foreach_step
"Step" or begin next iteration of foreach loop. Assigns to foreach
iteration variables. May jump to straight after the foreach_start
that pushed the iterTracker and info values. MUST be followed
immediately by a foreach_end.
Stack: ... listObjs... iterTracker info => ... listObjs... iterTracker info
foreach_end
Clean up a foreach loop by dropping the info value, the tracker
value and the lists that were being iterated over.
Stack: ... listObjs... iterTracker info => ...
lmap_collect
Appends the value at the top of the stack to the list located on
the stack the "other side" of the foreach-related values.
Stack: ... collector listObjs... iterTracker info value => ... collector listObjs... iterTracker info
Variable List Append Operations
-------------------------------
lappendScalar1, LVT1
Lappend scalar variable at op1<=255 in frame; value is stktop
lappendScalar4, LVT4
Lappend scalar variable at op1 > 255 in frame; value is stktop
lappendArray1, LVT1
Lappend array element; array at op1<=255, value is top then elem
lappendArray4, LVT4
Lappend array element; array at op1>=256, value is top then elem
lappendArrayStk
Lappend array element; value is stktop, then elem, array names
lappendStk
Lappend general variable; value is stktop, then unparsed name
lappendList, LVT4
Lappend list to scalar variable at op4 in frame.
Stack: ... list => ... listVarContents
lappendListArray, LVT4
Lappend list to array element; array at op4.
Stack: ... elem list => ... listVarContents
lappendListArrayStk
Lappend list to array element.
Stack: ... arrayName elem list => ... listVarContents
lappendListStk
Lappend list to general variable.
Stack: ... varName list => ... listVarContents
List Operations
---------------
list, UINT4
List: push (stk1 stk2 ... stktop)
listIndex
List Index: push (listindex stknext stktop)
listLength
List Len: push (listlength stktop)
lindexMulti, UINT4
Lindex with generalized args, operand is number of stacked objs
used: (operand-1) entries from stktop are the indices; then list to
process.
lsetList
Four-arg version of 'lset'. stktop is old value; next is new
element value, next is the index list; pushes new value
lsetFlat, UINT4
Three- or >=5-arg version of 'lset', operand is number of stacked
objs: stktop is old value, next is new element value, next come
(operand-2) indices; pushes the new value.
listIndexImm, IDX4
List Index: push (lindex stktop op4)
listRangeImm, IDX4, IDX4
List Range: push (lrange stktop op4 op4)
listIn
List containment: push [lsearch stktop stknext]>=0)
listNotIn
List negated containment: push [lsearch stktop stknext]<0)
listConcat
Concatenates the two lists at the top of the stack into a single
list and pushes that resulting list onto the stack.
Stack: ... list1 list2 => ... [lconcat list1 list2]
concatStk, UINT4
Wrapper round Tcl_ConcatObj(), used for [concat] and [eval]. opnd
is number of values to concatenate.
Operation: push concat(stk1 stk2 ... stktop)
Dictionary Operations
---------------------
dictGet, UINT4
The top op4 words (min 1) are a key path into the dictionary just
below the keys on the stack, and all those values are replaced by
the value read out of that key-path (like [dict get]).
Stack: ... dict key1 ... keyN => ... value
dictSet, UINT4, LVT4
Update a dictionary value such that the keys are a path pointing to
the value. op4#1 = numKeys, op4#2 = LVTindex
Stack: ... key1 ... keyN value => ... newDict
dictUnset, UINT4, LVT4
Update a dictionary value such that the keys are not a path pointing
to any value. op4#1 = numKeys, op4#2 = LVTindex
Stack: ... key1 ... keyN => ... newDict
dictIncrImm, INT4, LVT4
Update a dictionary value such that the value pointed to by key is
incremented by some value (or set to it if the key isn't in the
dictionary at all). op4#1 = incrAmount, op4#2 = LVTindex
Stack: ... key => ... newDict
dictAppend, LVT4
Update a dictionary value such that the value pointed to by key has
some value string-concatenated onto it. op4 = LVTindex
Stack: ... key valueToAppend => ... newDict
dictLappend, LVT4
Update a dictionary value such that the value pointed to by key has
some value list-appended onto it. op4 = LVTindex
Stack: ... key valueToAppend => ... newDict
dictFirst, LVT4
Begin iterating over the dictionary, using the local scalar
indicated by op4 to hold the iterator state. The local scalar
should not refer to a named variable as the value is not wholly
managed correctly.
Stack: ... dict => ... value key doneBool
dictNext, LVT4
Get the next iteration from the iterator in op4's local scalar.
Stack: ... => ... value key doneBool
dictDone, LVT4
Terminate the iterator in op4's local scalar. Use unsetScalar
instead (with 0 for flags).
dictUpdateStart, LVT4, AUX4
Create the variables (described in the aux data referred to by the
second immediate argument) to mirror the state of the dictionary in
the variable referred to by the first immediate argument. The list
of keys (top of the stack, not poppsed) must be the same length as
the list of variables.
Stack: ... keyList => ... keyList
dictUpdateEnd, LVT4, AUX4
Reflect the state of local variables (described in the aux data
referred to by the second immediate argument) back to the state of
the dictionary in the variable referred to by the first immediate
argument. The list of keys (popped from the stack) must be the same
length as the list of variables.
Stack: ... keyList => ...
dictExpand
Probe into a dict and extract it (or a subdict of it) into
variables with matched names. Produces list of keys bound as
result. Part of [dict with].
Stack: ... dict path => ... keyList
dictRecombineStk
Map variable contents back into a dictionary in a variable. Part of
[dict with].
Stack: ... dictVarName path keyList => ...
dictRecombineImm, LVT4
Map variable contents back into a dictionary in the local variable
indicated by the LVT index. Part of [dict with].
Stack: ... path keyList => ...
dictExists, UINT4
The top op4 words (min 1) are a key path into the dictionary just
below the keys on the stack, and all those values are replaced by a
boolean indicating whether it is possible to read out a value from
that key-path (like [dict exists]).
Stack: ... dict key1 ... keyN => ... boolean
verifyDict
Verifies that the word on the top of the stack is a dictionary,
popping it if it is and throwing an error if it is not.
Stack: ... value => ...
Variable Linking Operations
---------------------------
upvar, LVT4
finds level and otherName in stack, links to local variable at
index op1. Leaves the level on stack.
nsupvar, LVT4
finds namespace and otherName in stack, links to local variable at
index op1. Leaves the namespace on stack.
variable, LVT4
finds namespace and otherName in stack, links to local variable at
index op1. Leaves the namespace on stack.
Variable Existance Operations
-----------------------------
existScalar, LVT4
Test if scalar variable at index op1 in call frame exists
existArray, LVT4
Test if array element exists; array at slot op1, element is
stktop
existArrayStk
Test if array element exists; element is stktop, array name is
stknext
existStk
Test if general variable exists; unparsed variable name is stktop
Variable Removal Operations
---------------------------
unsetScalar, UINT1, LVT4
Make scalar variable at index op2 in call frame cease to exist;
op1 is 1 for errors on problems, 0 otherwise
unsetArray, UINT1, LVT4
Make array element cease to exist; array at slot op2, element is
stktop; op1 is 1 for errors on problems, 0 otherwise
unsetArrayStk, UINT1
Make array element cease to exist; element is stktop, array name is
stknext; op1 is 1 for errors on problems, 0 otherwise
unsetStk, UINT1
Make general variable cease to exist; unparsed variable name is
stktop; op1 is 1 for errors on problems, 0 otherwise
NRE Operations
--------------
yield
Makes the current coroutine yield the value at the top of the
stack, and places the response back on top of the stack when it
resumes.
Stack: ... valueToYield => ... resumeValue
coroName
Push the name of the interpreter's current coroutine as an object
on the stack.
tailcall, UINT1
Do a tailcall with the opnd items on the stack as the thing to
tailcall to; opnd must be greater than 0 for the semantics to work
right.
yieldToInvoke
Makes the current coroutine yield the value at the top of the
stack, invoking the given command/args with resolution in the given
namespace (all packed into a list), and places the list of values
that are the response back on top of the stack when it resumes.
Stack: ... [list ns cmd arg1 ... argN] => ... resumeList
General Introspection Operations
--------------------------------
currentNamespace
Push the name of the interpreter's current namespace as an object
on the stack.
infoLevelNumber
Push the stack depth (i.e., [info level]) of the interpreter as an
object on the stack.
infoLevelArgs
Push the argument words to a stack depth (i.e., [info level <n>])
of the interpreter as an object on the stack.
Stack: ... depth => ... argList
resolveCmd
Resolves the command named on the top of the stack to its fully
qualified version, or produces the empty string if no such command
exists. Never generates errors.
Stack: ... cmdName => ... fullCmdName
originCmd
Reports which command was the origin (via namespace import chain)
of the command named on the top of the stack.
Stack: ... cmdName => ... fullOriginalCmdName
TclOO Operations
----------------
tclooSelf
Push the identity of the current TclOO object (i.e., the name of
its current public access command) on the stack.
tclooClass
Push the class of the TclOO object named at the top of the stack
onto the stack.
Stack: ... object => ... class
tclooNamespace
Push the namespace of the TclOO object named at the top of the
stack onto the stack.
Stack: ... object => ... namespace
tclooIsObject
Push whether the value named at the top of the stack is a TclOO
object (i.e., a boolean). Can corrupt the interpreter result
despite not throwing, so not safe for use in a post-exception
context.
Stack: ... value => ... boolean
tclooNext, UINT1
Call the next item on the TclOO call chain, passing opnd arguments
(min 1, max 255, *includes* "next"). The result of the invoked
method implementation will be pushed on the stack in place of the
arguments (similar to invokeStk).
Stack: ... "next" arg2 arg3 -- argN => ... result
tclooNextClass, UINT1
Call the following item on the TclOO call chain defined by class
className, passing opnd arguments (min 2, max 255, *includes*
"nextto" and the class name). The result of the invoked method
implementation will be pushed on the stack in place of the
arguments (similar to invokeStk).
Stack: ... "nextto" className arg3 arg4 -- argN => ... result
Array Operations
----------------
arrayExistsStk
Looks up the element on the top of the stack and tests whether it
is an array. Pushes a boolean describing whether this is the
case. Also runs the whole-array trace on the named variable, so can
throw anything.
Stack: ... varName => ... boolean
arrayExistsImm, UINT4
Looks up the variable indexed by opnd and tests whether it is an
array. Pushes a boolean describing whether this is the case. Also
runs the whole-array trace on the named variable, so can throw
anything.
Stack: ... => ... boolean
arrayMakeStk
Forces the element on the top of the stack to be the name of an
array.
Stack: ... varName => ...
arrayMakeImm, UINT4
Forces the variable indexed by opnd to be an array. Does not touch
the stack.
|