1 |
/* $Header$ */ |
2 |
/* |
3 |
* tclCompile.h -- |
4 |
* |
5 |
* Copyright (c) 1996-1998 Sun Microsystems, Inc. |
6 |
* |
7 |
* See the file "license.terms" for information on usage and redistribution |
8 |
* of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
9 |
* |
10 |
* RCS: @(#) $Id: tclcompile.h,v 1.1.1.1 2001/06/13 04:36:28 dtashley Exp $ |
11 |
*/ |
12 |
|
13 |
#ifndef _TCLCOMPILATION |
14 |
#define _TCLCOMPILATION 1 |
15 |
|
16 |
#ifndef _TCLINT |
17 |
#include "tclInt.h" |
18 |
#endif /* _TCLINT */ |
19 |
|
20 |
#ifdef BUILD_tcl |
21 |
# undef TCL_STORAGE_CLASS |
22 |
# define TCL_STORAGE_CLASS DLLEXPORT |
23 |
#endif |
24 |
|
25 |
/* |
26 |
*------------------------------------------------------------------------ |
27 |
* Variables related to compilation. These are used in tclCompile.c, |
28 |
* tclExecute.c, tclBasic.c, and their clients. |
29 |
*------------------------------------------------------------------------ |
30 |
*/ |
31 |
|
32 |
/* |
33 |
* Variable that denotes the command name Tcl object type. Objects of this |
34 |
* type cache the Command pointer that results from looking up command names |
35 |
* in the command hashtable. |
36 |
*/ |
37 |
|
38 |
extern Tcl_ObjType tclCmdNameType; |
39 |
|
40 |
/* |
41 |
* Variable that controls whether compilation tracing is enabled and, if so, |
42 |
* what level of tracing is desired: |
43 |
* 0: no compilation tracing |
44 |
* 1: summarize compilation of top level cmds and proc bodies |
45 |
* 2: display all instructions of each ByteCode compiled |
46 |
* This variable is linked to the Tcl variable "tcl_traceCompile". |
47 |
*/ |
48 |
|
49 |
extern int tclTraceCompile; |
50 |
|
51 |
/* |
52 |
* Variable that controls whether execution tracing is enabled and, if so, |
53 |
* what level of tracing is desired: |
54 |
* 0: no execution tracing |
55 |
* 1: trace invocations of Tcl procs only |
56 |
* 2: trace invocations of all (not compiled away) commands |
57 |
* 3: display each instruction executed |
58 |
* This variable is linked to the Tcl variable "tcl_traceExec". |
59 |
*/ |
60 |
|
61 |
extern int tclTraceExec; |
62 |
|
63 |
/* |
64 |
*------------------------------------------------------------------------ |
65 |
* Data structures related to compilation. |
66 |
*------------------------------------------------------------------------ |
67 |
*/ |
68 |
|
69 |
/* |
70 |
* The structure used to implement Tcl "exceptions" (exceptional returns): |
71 |
* for example, those generated in loops by the break and continue commands, |
72 |
* and those generated by scripts and caught by the catch command. This |
73 |
* ExceptionRange structure describes a range of code (e.g., a loop body), |
74 |
* the kind of exceptions (e.g., a break or continue) that might occur, and |
75 |
* the PC offsets to jump to if a matching exception does occur. Exception |
76 |
* ranges can nest so this structure includes a nesting level that is used |
77 |
* at runtime to find the closest exception range surrounding a PC. For |
78 |
* example, when a break command is executed, the ExceptionRange structure |
79 |
* for the most deeply nested loop, if any, is found and used. These |
80 |
* structures are also generated for the "next" subcommands of for loops |
81 |
* since a break there terminates the for command. This means a for command |
82 |
* actually generates two LoopInfo structures. |
83 |
*/ |
84 |
|
85 |
typedef enum { |
86 |
LOOP_EXCEPTION_RANGE, /* Exception's range is part of a loop. |
87 |
* Break and continue "exceptions" cause |
88 |
* jumps to appropriate PC offsets. */ |
89 |
CATCH_EXCEPTION_RANGE /* Exception's range is controlled by a |
90 |
* catch command. Errors in the range cause |
91 |
* a jump to a catch PC offset. */ |
92 |
} ExceptionRangeType; |
93 |
|
94 |
typedef struct ExceptionRange { |
95 |
ExceptionRangeType type; /* The kind of ExceptionRange. */ |
96 |
int nestingLevel; /* Static depth of the exception range. |
97 |
* Used to find the most deeply-nested |
98 |
* range surrounding a PC at runtime. */ |
99 |
int codeOffset; /* Offset of the first instruction byte of |
100 |
* the code range. */ |
101 |
int numCodeBytes; /* Number of bytes in the code range. */ |
102 |
int breakOffset; /* If LOOP_EXCEPTION_RANGE, the target PC |
103 |
* offset for a break command in the range. */ |
104 |
int continueOffset; /* If LOOP_EXCEPTION_RANGE and not -1, the |
105 |
* target PC offset for a continue command in |
106 |
* the code range. Otherwise, ignore this range |
107 |
* when processing a continue command. */ |
108 |
int catchOffset; /* If a CATCH_EXCEPTION_RANGE, the target PC |
109 |
* offset for any "exception" in range. */ |
110 |
} ExceptionRange; |
111 |
|
112 |
/* |
113 |
* Structure used to map between instruction pc and source locations. It |
114 |
* defines for each compiled Tcl command its code's starting offset and |
115 |
* its source's starting offset and length. Note that the code offset |
116 |
* increases monotonically: that is, the table is sorted in code offset |
117 |
* order. The source offset is not monotonic. |
118 |
*/ |
119 |
|
120 |
typedef struct CmdLocation { |
121 |
int codeOffset; /* Offset of first byte of command code. */ |
122 |
int numCodeBytes; /* Number of bytes for command's code. */ |
123 |
int srcOffset; /* Offset of first char of the command. */ |
124 |
int numSrcBytes; /* Number of command source chars. */ |
125 |
} CmdLocation; |
126 |
|
127 |
/* |
128 |
* CompileProcs need the ability to record information during compilation |
129 |
* that can be used by bytecode instructions during execution. The AuxData |
130 |
* structure provides this "auxiliary data" mechanism. An arbitrary number |
131 |
* of these structures can be stored in the ByteCode record (during |
132 |
* compilation they are stored in a CompileEnv structure). Each AuxData |
133 |
* record holds one word of client-specified data (often a pointer) and is |
134 |
* given an index that instructions can later use to look up the structure |
135 |
* and its data. |
136 |
* |
137 |
* The following definitions declare the types of procedures that are called |
138 |
* to duplicate or free this auxiliary data when the containing ByteCode |
139 |
* objects are duplicated and freed. Pointers to these procedures are kept |
140 |
* in the AuxData structure. |
141 |
*/ |
142 |
|
143 |
typedef ClientData (AuxDataDupProc) _ANSI_ARGS_((ClientData clientData)); |
144 |
typedef void (AuxDataFreeProc) _ANSI_ARGS_((ClientData clientData)); |
145 |
|
146 |
/* |
147 |
* We define a separate AuxDataType struct to hold type-related information |
148 |
* for the AuxData structure. This separation makes it possible for clients |
149 |
* outside of the TCL core to manipulate (in a limited fashion!) AuxData; |
150 |
* for example, it makes it possible to pickle and unpickle AuxData structs. |
151 |
*/ |
152 |
|
153 |
typedef struct AuxDataType { |
154 |
char *name; /* the name of the type. Types can be |
155 |
* registered and found by name */ |
156 |
AuxDataDupProc *dupProc; /* Callback procedure to invoke when the |
157 |
* aux data is duplicated (e.g., when the |
158 |
* ByteCode structure containing the aux |
159 |
* data is duplicated). NULL means just |
160 |
* copy the source clientData bits; no |
161 |
* proc need be called. */ |
162 |
AuxDataFreeProc *freeProc; /* Callback procedure to invoke when the |
163 |
* aux data is freed. NULL means no |
164 |
* proc need be called. */ |
165 |
} AuxDataType; |
166 |
|
167 |
/* |
168 |
* The definition of the AuxData structure that holds information created |
169 |
* during compilation by CompileProcs and used by instructions during |
170 |
* execution. |
171 |
*/ |
172 |
|
173 |
typedef struct AuxData { |
174 |
AuxDataType *type; /* pointer to the AuxData type associated with |
175 |
* this ClientData. */ |
176 |
ClientData clientData; /* The compilation data itself. */ |
177 |
} AuxData; |
178 |
|
179 |
/* |
180 |
* Structure defining the compilation environment. After compilation, fields |
181 |
* describing bytecode instructions are copied out into the more compact |
182 |
* ByteCode structure defined below. |
183 |
*/ |
184 |
|
185 |
#define COMPILEENV_INIT_CODE_BYTES 250 |
186 |
#define COMPILEENV_INIT_NUM_OBJECTS 60 |
187 |
#define COMPILEENV_INIT_EXCEPT_RANGES 5 |
188 |
#define COMPILEENV_INIT_CMD_MAP_SIZE 40 |
189 |
#define COMPILEENV_INIT_AUX_DATA_SIZE 5 |
190 |
|
191 |
typedef struct CompileEnv { |
192 |
Interp *iPtr; /* Interpreter containing the code being |
193 |
* compiled. Commands and their compile |
194 |
* procs are specific to an interpreter so |
195 |
* the code emitted will depend on the |
196 |
* interpreter. */ |
197 |
char *source; /* The source string being compiled by |
198 |
* SetByteCodeFromAny. This pointer is not |
199 |
* owned by the CompileEnv and must not be |
200 |
* freed or changed by it. */ |
201 |
int numSrcBytes; /* Number of bytes in source. */ |
202 |
Proc *procPtr; /* If a procedure is being compiled, a |
203 |
* pointer to its Proc structure; otherwise |
204 |
* NULL. Used to compile local variables. |
205 |
* Set from information provided by |
206 |
* ObjInterpProc in tclProc.c. */ |
207 |
int numCommands; /* Number of commands compiled. */ |
208 |
int exceptDepth; /* Current exception range nesting level; |
209 |
* -1 if not in any range currently. */ |
210 |
int maxExceptDepth; /* Max nesting level of exception ranges; |
211 |
* -1 if no ranges have been compiled. */ |
212 |
int maxStackDepth; /* Maximum number of stack elements needed |
213 |
* to execute the code. Set by compilation |
214 |
* procedures before returning. */ |
215 |
LiteralTable localLitTable; /* Contains LiteralEntry's describing |
216 |
* all Tcl objects referenced by this |
217 |
* compiled code. Indexed by the string |
218 |
* representations of the literals. Used to |
219 |
* avoid creating duplicate objects. */ |
220 |
int exprIsJustVarRef; /* Set 1 if the expression last compiled by |
221 |
* TclCompileExpr consisted of just a |
222 |
* variable reference as in the expression |
223 |
* of "if $b then...". Otherwise 0. Used |
224 |
* to implement expr's 2 level substitution |
225 |
* semantics properly. */ |
226 |
int exprIsComparison; /* Set 1 if the top-level operator in the |
227 |
* expression last compiled is a comparison. |
228 |
* Otherwise 0. If 1, since the operands |
229 |
* might be strings, the expr is compiled |
230 |
* out-of-line to implement expr's 2 level |
231 |
* substitution semantics properly. */ |
232 |
unsigned char *codeStart; /* Points to the first byte of the code. */ |
233 |
unsigned char *codeNext; /* Points to next code array byte to use. */ |
234 |
unsigned char *codeEnd; /* Points just after the last allocated |
235 |
* code array byte. */ |
236 |
int mallocedCodeArray; /* Set 1 if code array was expanded |
237 |
* and codeStart points into the heap.*/ |
238 |
LiteralEntry *literalArrayPtr; |
239 |
/* Points to start of LiteralEntry array. */ |
240 |
int literalArrayNext; /* Index of next free object array entry. */ |
241 |
int literalArrayEnd; /* Index just after last obj array entry. */ |
242 |
int mallocedLiteralArray; /* 1 if object array was expanded and |
243 |
* objArray points into the heap, else 0. */ |
244 |
ExceptionRange *exceptArrayPtr; |
245 |
/* Points to start of the ExceptionRange |
246 |
* array. */ |
247 |
int exceptArrayNext; /* Next free ExceptionRange array index. |
248 |
* exceptArrayNext is the number of ranges |
249 |
* and (exceptArrayNext-1) is the index of |
250 |
* the current range's array entry. */ |
251 |
int exceptArrayEnd; /* Index after the last ExceptionRange |
252 |
* array entry. */ |
253 |
int mallocedExceptArray; /* 1 if ExceptionRange array was expanded |
254 |
* and exceptArrayPtr points in heap, |
255 |
* else 0. */ |
256 |
CmdLocation *cmdMapPtr; /* Points to start of CmdLocation array. |
257 |
* numCommands is the index of the next |
258 |
* entry to use; (numCommands-1) is the |
259 |
* entry index for the last command. */ |
260 |
int cmdMapEnd; /* Index after last CmdLocation entry. */ |
261 |
int mallocedCmdMap; /* 1 if command map array was expanded and |
262 |
* cmdMapPtr points in the heap, else 0. */ |
263 |
AuxData *auxDataArrayPtr; /* Points to auxiliary data array start. */ |
264 |
int auxDataArrayNext; /* Next free compile aux data array index. |
265 |
* auxDataArrayNext is the number of aux |
266 |
* data items and (auxDataArrayNext-1) is |
267 |
* index of current aux data array entry. */ |
268 |
int auxDataArrayEnd; /* Index after last aux data array entry. */ |
269 |
int mallocedAuxDataArray; /* 1 if aux data array was expanded and |
270 |
* auxDataArrayPtr points in heap else 0. */ |
271 |
unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES]; |
272 |
/* Initial storage for code. */ |
273 |
LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS]; |
274 |
/* Initial storage of LiteralEntry array. */ |
275 |
ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES]; |
276 |
/* Initial ExceptionRange array storage. */ |
277 |
CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE]; |
278 |
/* Initial storage for cmd location map. */ |
279 |
AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE]; |
280 |
/* Initial storage for aux data array. */ |
281 |
} CompileEnv; |
282 |
|
283 |
/* |
284 |
* The structure defining the bytecode instructions resulting from compiling |
285 |
* a Tcl script. Note that this structure is variable length: a single heap |
286 |
* object is allocated to hold the ByteCode structure immediately followed |
287 |
* by the code bytes, the literal object array, the ExceptionRange array, |
288 |
* the CmdLocation map, and the compilation AuxData array. |
289 |
*/ |
290 |
|
291 |
/* |
292 |
* A PRECOMPILED bytecode struct is one that was generated from a compiled |
293 |
* image rather than implicitly compiled from source |
294 |
*/ |
295 |
#define TCL_BYTECODE_PRECOMPILED 0x0001 |
296 |
|
297 |
typedef struct ByteCode { |
298 |
TclHandle interpHandle; /* Handle for interpreter containing the |
299 |
* compiled code. Commands and their compile |
300 |
* procs are specific to an interpreter so the |
301 |
* code emitted will depend on the |
302 |
* interpreter. */ |
303 |
int compileEpoch; /* Value of iPtr->compileEpoch when this |
304 |
* ByteCode was compiled. Used to invalidate |
305 |
* code when, e.g., commands with compile |
306 |
* procs are redefined. */ |
307 |
Namespace *nsPtr; /* Namespace context in which this code |
308 |
* was compiled. If the code is executed |
309 |
* if a different namespace, it must be |
310 |
* recompiled. */ |
311 |
int nsEpoch; /* Value of nsPtr->resolverEpoch when this |
312 |
* ByteCode was compiled. Used to invalidate |
313 |
* code when new namespace resolution rules |
314 |
* are put into effect. */ |
315 |
int refCount; /* Reference count: set 1 when created |
316 |
* plus 1 for each execution of the code |
317 |
* currently active. This structure can be |
318 |
* freed when refCount becomes zero. */ |
319 |
unsigned int flags; /* flags describing state for the codebyte. |
320 |
* this variable holds ORed values from the |
321 |
* TCL_BYTECODE_ masks defined above */ |
322 |
char *source; /* The source string from which this |
323 |
* ByteCode was compiled. Note that this |
324 |
* pointer is not owned by the ByteCode and |
325 |
* must not be freed or modified by it. */ |
326 |
Proc *procPtr; /* If the ByteCode was compiled from a |
327 |
* procedure body, this is a pointer to its |
328 |
* Proc structure; otherwise NULL. This |
329 |
* pointer is also not owned by the ByteCode |
330 |
* and must not be freed by it. */ |
331 |
size_t structureSize; /* Number of bytes in the ByteCode structure |
332 |
* itself. Does not include heap space for |
333 |
* literal Tcl objects or storage referenced |
334 |
* by AuxData entries. */ |
335 |
int numCommands; /* Number of commands compiled. */ |
336 |
int numSrcBytes; /* Number of source bytes compiled. */ |
337 |
int numCodeBytes; /* Number of code bytes. */ |
338 |
int numLitObjects; /* Number of objects in literal array. */ |
339 |
int numExceptRanges; /* Number of ExceptionRange array elems. */ |
340 |
int numAuxDataItems; /* Number of AuxData items. */ |
341 |
int numCmdLocBytes; /* Number of bytes needed for encoded |
342 |
* command location information. */ |
343 |
int maxExceptDepth; /* Maximum nesting level of ExceptionRanges; |
344 |
* -1 if no ranges were compiled. */ |
345 |
int maxStackDepth; /* Maximum number of stack elements needed |
346 |
* to execute the code. */ |
347 |
unsigned char *codeStart; /* Points to the first byte of the code. |
348 |
* This is just after the final ByteCode |
349 |
* member cmdMapPtr. */ |
350 |
Tcl_Obj **objArrayPtr; /* Points to the start of the literal |
351 |
* object array. This is just after the |
352 |
* last code byte. */ |
353 |
ExceptionRange *exceptArrayPtr; |
354 |
/* Points to the start of the ExceptionRange |
355 |
* array. This is just after the last |
356 |
* object in the object array. */ |
357 |
AuxData *auxDataArrayPtr; /* Points to the start of the auxiliary data |
358 |
* array. This is just after the last entry |
359 |
* in the ExceptionRange array. */ |
360 |
unsigned char *codeDeltaStart; |
361 |
/* Points to the first of a sequence of |
362 |
* bytes that encode the change in the |
363 |
* starting offset of each command's code. |
364 |
* If -127<=delta<=127, it is encoded as 1 |
365 |
* byte, otherwise 0xFF (128) appears and |
366 |
* the delta is encoded by the next 4 bytes. |
367 |
* Code deltas are always positive. This |
368 |
* sequence is just after the last entry in |
369 |
* the AuxData array. */ |
370 |
unsigned char *codeLengthStart; |
371 |
/* Points to the first of a sequence of |
372 |
* bytes that encode the length of each |
373 |
* command's code. The encoding is the same |
374 |
* as for code deltas. Code lengths are |
375 |
* always positive. This sequence is just |
376 |
* after the last entry in the code delta |
377 |
* sequence. */ |
378 |
unsigned char *srcDeltaStart; |
379 |
/* Points to the first of a sequence of |
380 |
* bytes that encode the change in the |
381 |
* starting offset of each command's source. |
382 |
* The encoding is the same as for code |
383 |
* deltas. Source deltas can be negative. |
384 |
* This sequence is just after the last byte |
385 |
* in the code length sequence. */ |
386 |
unsigned char *srcLengthStart; |
387 |
/* Points to the first of a sequence of |
388 |
* bytes that encode the length of each |
389 |
* command's source. The encoding is the |
390 |
* same as for code deltas. Source lengths |
391 |
* are always positive. This sequence is |
392 |
* just after the last byte in the source |
393 |
* delta sequence. */ |
394 |
#ifdef TCL_COMPILE_STATS |
395 |
Tcl_Time createTime; /* Absolute time when the ByteCode was |
396 |
* created. */ |
397 |
#endif /* TCL_COMPILE_STATS */ |
398 |
} ByteCode; |
399 |
|
400 |
/* |
401 |
* Opcodes for the Tcl bytecode instructions. These must correspond to the |
402 |
* entries in the table of instruction descriptions, instructionTable, in |
403 |
* tclCompile.c. Also, the order and number of the expression opcodes |
404 |
* (e.g., INST_LOR) must match the entries in the array operatorStrings in |
405 |
* tclExecute.c. |
406 |
*/ |
407 |
|
408 |
/* Opcodes 0 to 9 */ |
409 |
#define INST_DONE 0 |
410 |
#define INST_PUSH1 1 |
411 |
#define INST_PUSH4 2 |
412 |
#define INST_POP 3 |
413 |
#define INST_DUP 4 |
414 |
#define INST_CONCAT1 5 |
415 |
#define INST_INVOKE_STK1 6 |
416 |
#define INST_INVOKE_STK4 7 |
417 |
#define INST_EVAL_STK 8 |
418 |
#define INST_EXPR_STK 9 |
419 |
|
420 |
/* Opcodes 10 to 23 */ |
421 |
#define INST_LOAD_SCALAR1 10 |
422 |
#define INST_LOAD_SCALAR4 11 |
423 |
#define INST_LOAD_SCALAR_STK 12 |
424 |
#define INST_LOAD_ARRAY1 13 |
425 |
#define INST_LOAD_ARRAY4 14 |
426 |
#define INST_LOAD_ARRAY_STK 15 |
427 |
#define INST_LOAD_STK 16 |
428 |
#define INST_STORE_SCALAR1 17 |
429 |
#define INST_STORE_SCALAR4 18 |
430 |
#define INST_STORE_SCALAR_STK 19 |
431 |
#define INST_STORE_ARRAY1 20 |
432 |
#define INST_STORE_ARRAY4 21 |
433 |
#define INST_STORE_ARRAY_STK 22 |
434 |
#define INST_STORE_STK 23 |
435 |
|
436 |
/* Opcodes 24 to 33 */ |
437 |
#define INST_INCR_SCALAR1 24 |
438 |
#define INST_INCR_SCALAR_STK 25 |
439 |
#define INST_INCR_ARRAY1 26 |
440 |
#define INST_INCR_ARRAY_STK 27 |
441 |
#define INST_INCR_STK 28 |
442 |
#define INST_INCR_SCALAR1_IMM 29 |
443 |
#define INST_INCR_SCALAR_STK_IMM 30 |
444 |
#define INST_INCR_ARRAY1_IMM 31 |
445 |
#define INST_INCR_ARRAY_STK_IMM 32 |
446 |
#define INST_INCR_STK_IMM 33 |
447 |
|
448 |
/* Opcodes 34 to 39 */ |
449 |
#define INST_JUMP1 34 |
450 |
#define INST_JUMP4 35 |
451 |
#define INST_JUMP_TRUE1 36 |
452 |
#define INST_JUMP_TRUE4 37 |
453 |
#define INST_JUMP_FALSE1 38 |
454 |
#define INST_JUMP_FALSE4 39 |
455 |
|
456 |
/* Opcodes 40 to 64 */ |
457 |
#define INST_LOR 40 |
458 |
#define INST_LAND 41 |
459 |
#define INST_BITOR 42 |
460 |
#define INST_BITXOR 43 |
461 |
#define INST_BITAND 44 |
462 |
#define INST_EQ 45 |
463 |
#define INST_NEQ 46 |
464 |
#define INST_LT 47 |
465 |
#define INST_GT 48 |
466 |
#define INST_LE 49 |
467 |
#define INST_GE 50 |
468 |
#define INST_LSHIFT 51 |
469 |
#define INST_RSHIFT 52 |
470 |
#define INST_ADD 53 |
471 |
#define INST_SUB 54 |
472 |
#define INST_MULT 55 |
473 |
#define INST_DIV 56 |
474 |
#define INST_MOD 57 |
475 |
#define INST_UPLUS 58 |
476 |
#define INST_UMINUS 59 |
477 |
#define INST_BITNOT 60 |
478 |
#define INST_LNOT 61 |
479 |
#define INST_CALL_BUILTIN_FUNC1 62 |
480 |
#define INST_CALL_FUNC1 63 |
481 |
#define INST_TRY_CVT_TO_NUMERIC 64 |
482 |
|
483 |
/* Opcodes 65 to 66 */ |
484 |
#define INST_BREAK 65 |
485 |
#define INST_CONTINUE 66 |
486 |
|
487 |
/* Opcodes 67 to 68 */ |
488 |
#define INST_FOREACH_START4 67 |
489 |
#define INST_FOREACH_STEP4 68 |
490 |
|
491 |
/* Opcodes 69 to 72 */ |
492 |
#define INST_BEGIN_CATCH4 69 |
493 |
#define INST_END_CATCH 70 |
494 |
#define INST_PUSH_RESULT 71 |
495 |
#define INST_PUSH_RETURN_CODE 72 |
496 |
|
497 |
/* The last opcode */ |
498 |
#define LAST_INST_OPCODE 72 |
499 |
|
500 |
/* |
501 |
* Table describing the Tcl bytecode instructions: their name (for |
502 |
* displaying code), total number of code bytes required (including |
503 |
* operand bytes), and a description of the type of each operand. |
504 |
* These operand types include signed and unsigned integers of length |
505 |
* one and four bytes. The unsigned integers are used for indexes or |
506 |
* for, e.g., the count of objects to push in a "push" instruction. |
507 |
*/ |
508 |
|
509 |
#define MAX_INSTRUCTION_OPERANDS 2 |
510 |
|
511 |
typedef enum InstOperandType { |
512 |
OPERAND_NONE, |
513 |
OPERAND_INT1, /* One byte signed integer. */ |
514 |
OPERAND_INT4, /* Four byte signed integer. */ |
515 |
OPERAND_UINT1, /* One byte unsigned integer. */ |
516 |
OPERAND_UINT4 /* Four byte unsigned integer. */ |
517 |
} InstOperandType; |
518 |
|
519 |
typedef struct InstructionDesc { |
520 |
char *name; /* Name of instruction. */ |
521 |
int numBytes; /* Total number of bytes for instruction. */ |
522 |
int numOperands; /* Number of operands. */ |
523 |
InstOperandType opTypes[MAX_INSTRUCTION_OPERANDS]; |
524 |
/* The type of each operand. */ |
525 |
} InstructionDesc; |
526 |
|
527 |
extern InstructionDesc instructionTable[]; |
528 |
|
529 |
/* |
530 |
* Definitions of the values of the INST_CALL_BUILTIN_FUNC instruction's |
531 |
* operand byte. Each value denotes a builtin Tcl math function. These |
532 |
* values must correspond to the entries in the builtinFuncTable array |
533 |
* below and to the values stored in the tclInt.h MathFunc structure's |
534 |
* builtinFuncIndex field. |
535 |
*/ |
536 |
|
537 |
#define BUILTIN_FUNC_ACOS 0 |
538 |
#define BUILTIN_FUNC_ASIN 1 |
539 |
#define BUILTIN_FUNC_ATAN 2 |
540 |
#define BUILTIN_FUNC_ATAN2 3 |
541 |
#define BUILTIN_FUNC_CEIL 4 |
542 |
#define BUILTIN_FUNC_COS 5 |
543 |
#define BUILTIN_FUNC_COSH 6 |
544 |
#define BUILTIN_FUNC_EXP 7 |
545 |
#define BUILTIN_FUNC_FLOOR 8 |
546 |
#define BUILTIN_FUNC_FMOD 9 |
547 |
#define BUILTIN_FUNC_HYPOT 10 |
548 |
#define BUILTIN_FUNC_LOG 11 |
549 |
#define BUILTIN_FUNC_LOG10 12 |
550 |
#define BUILTIN_FUNC_POW 13 |
551 |
#define BUILTIN_FUNC_SIN 14 |
552 |
#define BUILTIN_FUNC_SINH 15 |
553 |
#define BUILTIN_FUNC_SQRT 16 |
554 |
#define BUILTIN_FUNC_TAN 17 |
555 |
#define BUILTIN_FUNC_TANH 18 |
556 |
#define BUILTIN_FUNC_ABS 19 |
557 |
#define BUILTIN_FUNC_DOUBLE 20 |
558 |
#define BUILTIN_FUNC_INT 21 |
559 |
#define BUILTIN_FUNC_RAND 22 |
560 |
#define BUILTIN_FUNC_ROUND 23 |
561 |
#define BUILTIN_FUNC_SRAND 24 |
562 |
|
563 |
#define LAST_BUILTIN_FUNC 24 |
564 |
|
565 |
/* |
566 |
* Table describing the built-in math functions. Entries in this table are |
567 |
* indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's |
568 |
* operand byte. |
569 |
*/ |
570 |
|
571 |
typedef int (CallBuiltinFuncProc) _ANSI_ARGS_((Tcl_Interp *interp, |
572 |
ExecEnv *eePtr, ClientData clientData)); |
573 |
|
574 |
typedef struct { |
575 |
char *name; /* Name of function. */ |
576 |
int numArgs; /* Number of arguments for function. */ |
577 |
Tcl_ValueType argTypes[MAX_MATH_ARGS]; |
578 |
/* Acceptable types for each argument. */ |
579 |
CallBuiltinFuncProc *proc; /* Procedure implementing this function. */ |
580 |
ClientData clientData; /* Additional argument to pass to the |
581 |
* function when invoking it. */ |
582 |
} BuiltinFunc; |
583 |
|
584 |
extern BuiltinFunc builtinFuncTable[]; |
585 |
|
586 |
/* |
587 |
* Compilation of some Tcl constructs such as if commands and the logical or |
588 |
* (||) and logical and (&&) operators in expressions requires the |
589 |
* generation of forward jumps. Since the PC target of these jumps isn't |
590 |
* known when the jumps are emitted, we record the offset of each jump in an |
591 |
* array of JumpFixup structures. There is one array for each sequence of |
592 |
* jumps to one target PC. When we learn the target PC, we update the jumps |
593 |
* with the correct distance. Also, if the distance is too great (> 127 |
594 |
* bytes), we replace the single-byte jump with a four byte jump |
595 |
* instruction, move the instructions after the jump down, and update the |
596 |
* code offsets for any commands between the jump and the target. |
597 |
*/ |
598 |
|
599 |
typedef enum { |
600 |
TCL_UNCONDITIONAL_JUMP, |
601 |
TCL_TRUE_JUMP, |
602 |
TCL_FALSE_JUMP |
603 |
} TclJumpType; |
604 |
|
605 |
typedef struct JumpFixup { |
606 |
TclJumpType jumpType; /* Indicates the kind of jump. */ |
607 |
int codeOffset; /* Offset of the first byte of the one-byte |
608 |
* forward jump's code. */ |
609 |
int cmdIndex; /* Index of the first command after the one |
610 |
* for which the jump was emitted. Used to |
611 |
* update the code offsets for subsequent |
612 |
* commands if the two-byte jump at jumpPc |
613 |
* must be replaced with a five-byte one. */ |
614 |
int exceptIndex; /* Index of the first range entry in the |
615 |
* ExceptionRange array after the current |
616 |
* one. This field is used to adjust the |
617 |
* code offsets in subsequent ExceptionRange |
618 |
* records when a jump is grown from 2 bytes |
619 |
* to 5 bytes. */ |
620 |
} JumpFixup; |
621 |
|
622 |
#define JUMPFIXUP_INIT_ENTRIES 10 |
623 |
|
624 |
typedef struct JumpFixupArray { |
625 |
JumpFixup *fixup; /* Points to start of jump fixup array. */ |
626 |
int next; /* Index of next free array entry. */ |
627 |
int end; /* Index of last usable entry in array. */ |
628 |
int mallocedArray; /* 1 if array was expanded and fixups points |
629 |
* into the heap, else 0. */ |
630 |
JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES]; |
631 |
/* Initial storage for jump fixup array. */ |
632 |
} JumpFixupArray; |
633 |
|
634 |
/* |
635 |
* The structure describing one variable list of a foreach command. Note |
636 |
* that only foreach commands inside procedure bodies are compiled inline so |
637 |
* a ForeachVarList structure always describes local variables. Furthermore, |
638 |
* only scalar variables are supported for inline-compiled foreach loops. |
639 |
*/ |
640 |
|
641 |
typedef struct ForeachVarList { |
642 |
int numVars; /* The number of variables in the list. */ |
643 |
int varIndexes[1]; /* An array of the indexes ("slot numbers") |
644 |
* for each variable in the procedure's |
645 |
* array of local variables. Only scalar |
646 |
* variables are supported. The actual |
647 |
* size of this field will be large enough |
648 |
* to numVars indexes. THIS MUST BE THE |
649 |
* LAST FIELD IN THE STRUCTURE! */ |
650 |
} ForeachVarList; |
651 |
|
652 |
/* |
653 |
* Structure used to hold information about a foreach command that is needed |
654 |
* during program execution. These structures are stored in CompileEnv and |
655 |
* ByteCode structures as auxiliary data. |
656 |
*/ |
657 |
|
658 |
typedef struct ForeachInfo { |
659 |
int numLists; /* The number of both the variable and value |
660 |
* lists of the foreach command. */ |
661 |
int firstValueTemp; /* Index of the first temp var in a proc |
662 |
* frame used to point to a value list. */ |
663 |
int loopCtTemp; /* Index of temp var in a proc frame |
664 |
* holding the loop's iteration count. Used |
665 |
* to determine next value list element to |
666 |
* assign each loop var. */ |
667 |
ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList |
668 |
* structures describing each var list. The |
669 |
* actual size of this field will be large |
670 |
* enough to numVars indexes. THIS MUST BE |
671 |
* THE LAST FIELD IN THE STRUCTURE! */ |
672 |
} ForeachInfo; |
673 |
|
674 |
extern AuxDataType tclForeachInfoType; |
675 |
|
676 |
/* |
677 |
* Structure containing a cached pointer to a command that is the result |
678 |
* of resolving the command's name in some namespace. It is the internal |
679 |
* representation for a cmdName object. It contains the pointer along |
680 |
* with some information that is used to check the pointer's validity. |
681 |
*/ |
682 |
|
683 |
typedef struct ResolvedCmdName { |
684 |
Command *cmdPtr; /* A cached Command pointer. */ |
685 |
Namespace *refNsPtr; /* Points to the namespace containing the |
686 |
* reference (not the namespace that |
687 |
* contains the referenced command). */ |
688 |
long refNsId; /* refNsPtr's unique namespace id. Used to |
689 |
* verify that refNsPtr is still valid |
690 |
* (e.g., it's possible that the cmd's |
691 |
* containing namespace was deleted and a |
692 |
* new one created at the same address). */ |
693 |
int refNsCmdEpoch; /* Value of the referencing namespace's |
694 |
* cmdRefEpoch when the pointer was cached. |
695 |
* Before using the cached pointer, we check |
696 |
* if the namespace's epoch was incremented; |
697 |
* if so, this cached pointer is invalid. */ |
698 |
int cmdEpoch; /* Value of the command's cmdEpoch when this |
699 |
* pointer was cached. Before using the |
700 |
* cached pointer, we check if the cmd's |
701 |
* epoch was incremented; if so, the cmd was |
702 |
* renamed, deleted, hidden, or exposed, and |
703 |
* so the pointer is invalid. */ |
704 |
int refCount; /* Reference count: 1 for each cmdName |
705 |
* object that has a pointer to this |
706 |
* ResolvedCmdName structure as its internal |
707 |
* rep. This structure can be freed when |
708 |
* refCount becomes zero. */ |
709 |
} ResolvedCmdName; |
710 |
|
711 |
/* |
712 |
*---------------------------------------------------------------- |
713 |
* Procedures shared among Tcl bytecode compilation and execution |
714 |
* modules but not used outside: |
715 |
*---------------------------------------------------------------- |
716 |
*/ |
717 |
|
718 |
EXTERN void TclCleanupByteCode _ANSI_ARGS_((ByteCode *codePtr)); |
719 |
EXTERN int TclCompileCmdWord _ANSI_ARGS_((Tcl_Interp *interp, |
720 |
Tcl_Token *tokenPtr, int count, |
721 |
CompileEnv *envPtr)); |
722 |
EXTERN int TclCompileExpr _ANSI_ARGS_((Tcl_Interp *interp, |
723 |
char *script, int numBytes, |
724 |
CompileEnv *envPtr)); |
725 |
EXTERN int TclCompileExprWords _ANSI_ARGS_((Tcl_Interp *interp, |
726 |
Tcl_Token *tokenPtr, int numWords, |
727 |
CompileEnv *envPtr)); |
728 |
EXTERN int TclCompileScript _ANSI_ARGS_((Tcl_Interp *interp, |
729 |
char *script, int numBytes, int nested, |
730 |
CompileEnv *envPtr)); |
731 |
EXTERN int TclCompileTokens _ANSI_ARGS_((Tcl_Interp *interp, |
732 |
Tcl_Token *tokenPtr, int count, |
733 |
CompileEnv *envPtr)); |
734 |
EXTERN int TclCreateAuxData _ANSI_ARGS_((ClientData clientData, |
735 |
AuxDataType *typePtr, CompileEnv *envPtr)); |
736 |
EXTERN int TclCreateExceptRange _ANSI_ARGS_(( |
737 |
ExceptionRangeType type, CompileEnv *envPtr)); |
738 |
EXTERN ExecEnv * TclCreateExecEnv _ANSI_ARGS_((Tcl_Interp *interp)); |
739 |
EXTERN void TclDeleteExecEnv _ANSI_ARGS_((ExecEnv *eePtr)); |
740 |
EXTERN void TclDeleteLiteralTable _ANSI_ARGS_(( |
741 |
Tcl_Interp *interp, LiteralTable *tablePtr)); |
742 |
EXTERN void TclEmitForwardJump _ANSI_ARGS_((CompileEnv *envPtr, |
743 |
TclJumpType jumpType, JumpFixup *jumpFixupPtr)); |
744 |
EXTERN ExceptionRange * TclGetExceptionRangeForPc _ANSI_ARGS_(( |
745 |
unsigned char *pc, int catchOnly, |
746 |
ByteCode* codePtr)); |
747 |
EXTERN InstructionDesc * TclGetInstructionTable _ANSI_ARGS_(()); |
748 |
EXTERN int TclExecuteByteCode _ANSI_ARGS_((Tcl_Interp *interp, |
749 |
ByteCode *codePtr)); |
750 |
EXTERN void TclExpandCodeArray _ANSI_ARGS_(( |
751 |
CompileEnv *envPtr)); |
752 |
EXTERN void TclExpandJumpFixupArray _ANSI_ARGS_(( |
753 |
JumpFixupArray *fixupArrayPtr)); |
754 |
EXTERN void TclFinalizeAuxDataTypeTable _ANSI_ARGS_((void)); |
755 |
EXTERN int TclFindCompiledLocal _ANSI_ARGS_((char *name, |
756 |
int nameChars, int create, int flags, |
757 |
Proc *procPtr)); |
758 |
EXTERN LiteralEntry * TclLookupLiteralEntry _ANSI_ARGS_(( |
759 |
Tcl_Interp *interp, Tcl_Obj *objPtr)); |
760 |
EXTERN int TclFixupForwardJump _ANSI_ARGS_(( |
761 |
CompileEnv *envPtr, JumpFixup *jumpFixupPtr, |
762 |
int jumpDist, int distThreshold)); |
763 |
EXTERN void TclFreeCompileEnv _ANSI_ARGS_((CompileEnv *envPtr)); |
764 |
EXTERN void TclFreeJumpFixupArray _ANSI_ARGS_(( |
765 |
JumpFixupArray *fixupArrayPtr)); |
766 |
EXTERN void TclInitAuxDataTypeTable _ANSI_ARGS_((void)); |
767 |
EXTERN void TclInitByteCodeObj _ANSI_ARGS_((Tcl_Obj *objPtr, |
768 |
CompileEnv *envPtr)); |
769 |
EXTERN void TclInitCompilation _ANSI_ARGS_((void)); |
770 |
EXTERN void TclInitCompileEnv _ANSI_ARGS_((Tcl_Interp *interp, |
771 |
CompileEnv *envPtr, char *string, |
772 |
int numBytes)); |
773 |
EXTERN void TclInitJumpFixupArray _ANSI_ARGS_(( |
774 |
JumpFixupArray *fixupArrayPtr)); |
775 |
EXTERN void TclInitLiteralTable _ANSI_ARGS_(( |
776 |
LiteralTable *tablePtr)); |
777 |
#ifdef TCL_COMPILE_STATS |
778 |
EXTERN char * TclLiteralStats _ANSI_ARGS_(( |
779 |
LiteralTable *tablePtr)); |
780 |
EXTERN int TclLog2 _ANSI_ARGS_((int value)); |
781 |
#endif |
782 |
#ifdef TCL_COMPILE_DEBUG |
783 |
EXTERN void TclPrintByteCodeObj _ANSI_ARGS_((Tcl_Interp *interp, |
784 |
Tcl_Obj *objPtr)); |
785 |
#endif |
786 |
EXTERN int TclPrintInstruction _ANSI_ARGS_((ByteCode* codePtr, |
787 |
unsigned char *pc)); |
788 |
EXTERN void TclPrintObject _ANSI_ARGS_((FILE *outFile, |
789 |
Tcl_Obj *objPtr, int maxChars)); |
790 |
EXTERN void TclPrintSource _ANSI_ARGS_((FILE *outFile, |
791 |
char *string, int maxChars)); |
792 |
EXTERN void TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr)); |
793 |
EXTERN int TclRegisterLiteral _ANSI_ARGS_((CompileEnv *envPtr, |
794 |
char *bytes, int length, int onHeap)); |
795 |
EXTERN void TclReleaseLiteral _ANSI_ARGS_((Tcl_Interp *interp, |
796 |
Tcl_Obj *objPtr)); |
797 |
EXTERN void TclSetCmdNameObj _ANSI_ARGS_((Tcl_Interp *interp, |
798 |
Tcl_Obj *objPtr, Command *cmdPtr)); |
799 |
#ifdef TCL_COMPILE_DEBUG |
800 |
EXTERN void TclVerifyGlobalLiteralTable _ANSI_ARGS_(( |
801 |
Interp *iPtr)); |
802 |
EXTERN void TclVerifyLocalLiteralTable _ANSI_ARGS_(( |
803 |
CompileEnv *envPtr)); |
804 |
#endif |
805 |
|
806 |
/* |
807 |
*---------------------------------------------------------------- |
808 |
* Macros used by Tcl bytecode compilation and execution modules |
809 |
* inside the Tcl core but not used outside. |
810 |
*---------------------------------------------------------------- |
811 |
*/ |
812 |
|
813 |
/* |
814 |
* Macro to emit an opcode byte into a CompileEnv's code array. |
815 |
* The ANSI C "prototype" for this macro is: |
816 |
* |
817 |
* EXTERN void TclEmitOpcode _ANSI_ARGS_((unsigned char op, |
818 |
* CompileEnv *envPtr)); |
819 |
*/ |
820 |
|
821 |
#define TclEmitOpcode(op, envPtr) \ |
822 |
if ((envPtr)->codeNext == (envPtr)->codeEnd) \ |
823 |
TclExpandCodeArray(envPtr); \ |
824 |
*(envPtr)->codeNext++ = (unsigned char) (op) |
825 |
|
826 |
/* |
827 |
* Macro to emit an integer operand. |
828 |
* The ANSI C "prototype" for this macro is: |
829 |
* |
830 |
* EXTERN void TclEmitInt1 _ANSI_ARGS_((int i, CompileEnv *envPtr)); |
831 |
*/ |
832 |
|
833 |
#define TclEmitInt1(i, envPtr) \ |
834 |
if ((envPtr)->codeNext == (envPtr)->codeEnd) \ |
835 |
TclExpandCodeArray(envPtr); \ |
836 |
*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i)) |
837 |
|
838 |
/* |
839 |
* Macros to emit an instruction with signed or unsigned integer operands. |
840 |
* Four byte integers are stored in "big-endian" order with the high order |
841 |
* byte stored at the lowest address. |
842 |
* The ANSI C "prototypes" for these macros are: |
843 |
* |
844 |
* EXTERN void TclEmitInstInt1 _ANSI_ARGS_((unsigned char op, int i, |
845 |
* CompileEnv *envPtr)); |
846 |
* EXTERN void TclEmitInstInt4 _ANSI_ARGS_((unsigned char op, int i, |
847 |
* CompileEnv *envPtr)); |
848 |
*/ |
849 |
|
850 |
#define TclEmitInstInt1(op, i, envPtr) \ |
851 |
if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) { \ |
852 |
TclExpandCodeArray(envPtr); \ |
853 |
} \ |
854 |
*(envPtr)->codeNext++ = (unsigned char) (op); \ |
855 |
*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i)) |
856 |
|
857 |
#define TclEmitInstInt4(op, i, envPtr) \ |
858 |
if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \ |
859 |
TclExpandCodeArray(envPtr); \ |
860 |
} \ |
861 |
*(envPtr)->codeNext++ = (unsigned char) (op); \ |
862 |
*(envPtr)->codeNext++ = \ |
863 |
(unsigned char) ((unsigned int) (i) >> 24); \ |
864 |
*(envPtr)->codeNext++ = \ |
865 |
(unsigned char) ((unsigned int) (i) >> 16); \ |
866 |
*(envPtr)->codeNext++ = \ |
867 |
(unsigned char) ((unsigned int) (i) >> 8); \ |
868 |
*(envPtr)->codeNext++ = \ |
869 |
(unsigned char) ((unsigned int) (i) ) |
870 |
|
871 |
/* |
872 |
* Macro to push a Tcl object onto the Tcl evaluation stack. It emits the |
873 |
* object's one or four byte array index into the CompileEnv's code |
874 |
* array. These support, respectively, a maximum of 256 (2**8) and 2**32 |
875 |
* objects in a CompileEnv. The ANSI C "prototype" for this macro is: |
876 |
* |
877 |
* EXTERN void TclEmitPush _ANSI_ARGS_((int objIndex, CompileEnv *envPtr)); |
878 |
*/ |
879 |
|
880 |
#define TclEmitPush(objIndex, envPtr) \ |
881 |
if ((objIndex) <= 255) { \ |
882 |
TclEmitInstInt1(INST_PUSH1, (objIndex), (envPtr)); \ |
883 |
} else { \ |
884 |
TclEmitInstInt4(INST_PUSH4, (objIndex), (envPtr)); \ |
885 |
} |
886 |
|
887 |
/* |
888 |
* Macros to update a (signed or unsigned) integer starting at a pointer. |
889 |
* The two variants depend on the number of bytes. The ANSI C "prototypes" |
890 |
* for these macros are: |
891 |
* |
892 |
* EXTERN void TclStoreInt1AtPtr _ANSI_ARGS_((int i, unsigned char *p)); |
893 |
* EXTERN void TclStoreInt4AtPtr _ANSI_ARGS_((int i, unsigned char *p)); |
894 |
*/ |
895 |
|
896 |
#define TclStoreInt1AtPtr(i, p) \ |
897 |
*(p) = (unsigned char) ((unsigned int) (i)) |
898 |
|
899 |
#define TclStoreInt4AtPtr(i, p) \ |
900 |
*(p) = (unsigned char) ((unsigned int) (i) >> 24); \ |
901 |
*(p+1) = (unsigned char) ((unsigned int) (i) >> 16); \ |
902 |
*(p+2) = (unsigned char) ((unsigned int) (i) >> 8); \ |
903 |
*(p+3) = (unsigned char) ((unsigned int) (i) ) |
904 |
|
905 |
/* |
906 |
* Macros to update instructions at a particular pc with a new op code |
907 |
* and a (signed or unsigned) int operand. The ANSI C "prototypes" for |
908 |
* these macros are: |
909 |
* |
910 |
* EXTERN void TclUpdateInstInt1AtPc _ANSI_ARGS_((unsigned char op, int i, |
911 |
* unsigned char *pc)); |
912 |
* EXTERN void TclUpdateInstInt4AtPc _ANSI_ARGS_((unsigned char op, int i, |
913 |
* unsigned char *pc)); |
914 |
*/ |
915 |
|
916 |
#define TclUpdateInstInt1AtPc(op, i, pc) \ |
917 |
*(pc) = (unsigned char) (op); \ |
918 |
TclStoreInt1AtPtr((i), ((pc)+1)) |
919 |
|
920 |
#define TclUpdateInstInt4AtPc(op, i, pc) \ |
921 |
*(pc) = (unsigned char) (op); \ |
922 |
TclStoreInt4AtPtr((i), ((pc)+1)) |
923 |
|
924 |
/* |
925 |
* Macros to get a signed integer (GET_INT{1,2}) or an unsigned int |
926 |
* (GET_UINT{1,2}) from a pointer. There are two variants for each |
927 |
* return type that depend on the number of bytes fetched. |
928 |
* The ANSI C "prototypes" for these macros are: |
929 |
* |
930 |
* EXTERN int TclGetInt1AtPtr _ANSI_ARGS_((unsigned char *p)); |
931 |
* EXTERN int TclGetInt4AtPtr _ANSI_ARGS_((unsigned char *p)); |
932 |
* EXTERN unsigned int TclGetUInt1AtPtr _ANSI_ARGS_((unsigned char *p)); |
933 |
* EXTERN unsigned int TclGetUInt4AtPtr _ANSI_ARGS_((unsigned char *p)); |
934 |
*/ |
935 |
|
936 |
/* |
937 |
* The TclGetInt1AtPtr macro is tricky because we want to do sign |
938 |
* extension on the 1-byte value. Unfortunately the "char" type isn't |
939 |
* signed on all platforms so sign-extension doesn't always happen |
940 |
* automatically. Sometimes we can explicitly declare the pointer to be |
941 |
* signed, but other times we have to explicitly sign-extend the value |
942 |
* in software. |
943 |
*/ |
944 |
|
945 |
#ifndef __CHAR_UNSIGNED__ |
946 |
# define TclGetInt1AtPtr(p) ((int) *((char *) p)) |
947 |
#else |
948 |
# ifdef HAVE_SIGNED_CHAR |
949 |
# define TclGetInt1AtPtr(p) ((int) *((signed char *) p)) |
950 |
# else |
951 |
# define TclGetInt1AtPtr(p) (((int) *((char *) p)) \ |
952 |
| ((*(p) & 0200) ? (-256) : 0)) |
953 |
# endif |
954 |
#endif |
955 |
|
956 |
#define TclGetInt4AtPtr(p) (((int) TclGetInt1AtPtr(p) << 24) | \ |
957 |
(*((p)+1) << 16) | \ |
958 |
(*((p)+2) << 8) | \ |
959 |
(*((p)+3))) |
960 |
|
961 |
#define TclGetUInt1AtPtr(p) ((unsigned int) *(p)) |
962 |
#define TclGetUInt4AtPtr(p) ((unsigned int) (*(p) << 24) | \ |
963 |
(*((p)+1) << 16) | \ |
964 |
(*((p)+2) << 8) | \ |
965 |
(*((p)+3))) |
966 |
|
967 |
/* |
968 |
* Macros used to compute the minimum and maximum of two integers. |
969 |
* The ANSI C "prototypes" for these macros are: |
970 |
* |
971 |
* EXTERN int TclMin _ANSI_ARGS_((int i, int j)); |
972 |
* EXTERN int TclMax _ANSI_ARGS_((int i, int j)); |
973 |
*/ |
974 |
|
975 |
#define TclMin(i, j) ((((int) i) < ((int) j))? (i) : (j)) |
976 |
#define TclMax(i, j) ((((int) i) > ((int) j))? (i) : (j)) |
977 |
|
978 |
# undef TCL_STORAGE_CLASS |
979 |
# define TCL_STORAGE_CLASS DLLIMPORT |
980 |
|
981 |
#endif /* _TCLCOMPILATION */ |
982 |
|
983 |
/* End of tclcompile.h */ |