forked from tcltk-depot/tbcload
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcmpInt.h
More file actions
359 lines (314 loc) · 11.9 KB
/
Copy pathcmpInt.h
File metadata and controls
359 lines (314 loc) · 11.9 KB
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
/*
* cmpInt.h --
*
* Internal header file for the Compiler/Loader package.
* This header defines a number of macros that are used by both the writer
* and reader package to initialize some static variables. We use macros
* because the writer and the reader are two separate packages, and we don't
* want to share code between the two.
*
* Copyright (c) 1998-2000 Ajuba Solutions
* Copyright (c) 2002-2014, 2017 ActiveState Software Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: cmpInt.h,v 1.6 2002/12/02 17:42:02 andreas_kupries Exp $
*/
#ifndef _CMPINT_H
#define _CMPINT_H
#include <stdint.h>
#define HAVE_INTPTR_T
#include "tclCompile.h"
#include "tclInt.h"
#include "tclPort.h"
/*
* Polyfills for missing definitions in Tcl 8
*/
#if TCL_MAJOR_VERSION < 9
#ifdef Tcl_Size
#undef Tcl_Size
#endif
typedef int Tcl_Size;
#define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj
#define Tcl_NewSizeIntObj Tcl_NewIntObj
#define TCL_SIZE_MAX INT_MAX
#define TCL_SIZE_MODIFIER ""
typedef union Tcl_ObjInternalRep {
long longValue;
double doubleValue;
void *otherValuePtr;
Tcl_WideInt wideValue;
struct {
void *ptr1;
void *ptr2;
} twoPtrValue;
struct {
void *ptr;
unsigned long value;
} ptrAndLongRep;
} Tcl_ObjInternalRep;
static inline int
Tcl_HasInternalRep(Tcl_Obj *objPtr, const Tcl_ObjType *type) {
return objPtr->typePtr == type;
}
static inline Tcl_ObjInternalRep *
Tcl_FetchInternalRep(Tcl_Obj *objPtr, const Tcl_ObjType *type) {
return Tcl_HasInternalRep(objPtr, type) ?
(Tcl_ObjInternalRep *)(&objPtr->internalRep)
: NULL;
}
static inline void
Tcl_FreeInternalRep(Tcl_Obj *objPtr) {
if (objPtr->typePtr != NULL) {
if (objPtr->typePtr->freeIntRepProc != NULL) {
objPtr->typePtr->freeIntRepProc(objPtr);
}
objPtr->typePtr = NULL;
}
}
static inline void
Tcl_StoreInternalRep(Tcl_Obj *objPtr, const Tcl_ObjType *typePtr,
const Tcl_ObjInternalRep *irPtr) {
Tcl_FreeInternalRep(objPtr);
/* When irPtr == NULL, just leave objPtr with no internalrep for typePtr */
if (irPtr) {
objPtr->internalRep.twoPtrValue.ptr1 = irPtr->twoPtrValue.ptr1;
objPtr->internalRep.twoPtrValue.ptr2 = irPtr->twoPtrValue.ptr2;
objPtr->typePtr = typePtr;
}
}
#endif /* TCL_MAJOR_VERSION < 8 */
/*
* USE_CATCH_WRAPPER controls whether the emitted code has a catch around
* the call to loader::bceval and code to strip off the additional back trace
* from the error info
*/
#define USE_CATCH_WRAPPER 0
/*
* This macro includes code that emits and reads the location map for a
* ByteCode struct. The location map is useful only if the source is shipped
* (which does not happen currently), but we need to populate a location
* map in the ByteCode because some code in TCL core needs (for example, the
* code that generates errorInfo uses this map to find the source of the
* command corresponding to the pc that caused an exception).
*
* If EMIT_SRCMAP is 1, both the code arrays and the source arrays from the
* location map are emitted and extracted.
* If it is 0, only the code arrays are emitted; the source arrays are
* generated using the dummy source noSourceCode.
*/
/* #define EMIT_SRCMAP 0 */
/*
* structure to hold the calculated lengths of the location information
* arrays for a ByteCode structure
*/
typedef struct LocMapSizes
{
Tcl_Size codeDeltaSize; /* size of the codeDeltaStart array */
Tcl_Size codeLengthSize; /* size of the codeLengthStart array */
Tcl_Size srcDeltaSize; /* size of the srcDeltaStart array */
Tcl_Size srcLengthSize; /* size of the srcLengthStart array */
} LocMapSizes;
/*
* Map between ExceptionRangeType enums and type codes
*/
typedef struct ExcRangeMap
{
ExceptionRangeType type; /* The TCL enum for a given exception range type */
char name; /* and its corresponding code */
} ExcRangeMap;
/*
* An InstLocList structure holds the location in the bytecode of a PUSH
* instruction.
* It is used to keep track of a few different things:
* - the beginning of a call to "proc"
* - instructions that push a given object.
*
* This struct is exported for use by the compiler test package, otherwise
* it could be kept local to the writer.
*/
typedef struct InstLocList
{
struct InstLocList* next; /* next proc location in the list */
Tcl_Size bytecodeOffset; /* offset to the fist byte in the instruction */
Tcl_Size commandIndex; /* the command to which this instruction belongs */
} InstLocList;
/*
* A ProcBodyInfo structure holds the information we need to postprocess a
* procedure body. If the indices are set to -1, then the step that populated
* the struct detected that the body should not be compiled.
*
* This struct is exported for use by the compiler test package, otherwise it
* could be kept local to the writer.
*/
typedef struct ProcBodyInfo
{
Tcl_Size nameIndex; /* index in the object table of the object
* containing the name of the proc */
Tcl_Size argsIndex; /* index in the object table of the object
* containing the argument list for the proc */
Tcl_Size bodyOrigIndex; /* the original index in the object table of
* the object containing the body of the
* procedure */
Tcl_Size bodyNewIndex; /* the new index in the object table of the
* object containing the body of the procedure.
* The index is different from the original if
* the object had been shared */
Tcl_Size procOffset; /* offset to the location in the bytecodes
* where the "proc" string is pushed on the
* stack. This is the start of the instruction
* group for a proc command execution */
Tcl_Size bodyOffset; /* offset to the location in the bytecodes
* where this procedure body is pushed on the
* stack */
Tcl_Size commandIndex; /* the command number for this proc; values
* start at 0 for the first command in the
* script. */
} ProcBodyInfo;
/*
* The PostProcessInfo struct holds compilation info used by the compiler to
* postprocess the compiled proc body. The counters numProcs, numCompiledBodies,
* and numUnshared are on a compilation by compilation basis (they refer to the
* current compilation), whereas the counter in the CompilerContext struct
* defined below are cumulative for all compilations.
*
* This struct is exported for use by the compiler test package, otherwise it
* could be kept local to the writer.
*/
typedef struct PostProcessInfo
{
struct InstLocList* procs; /* the list of proc locations */
Tcl_Size numProcs; /* how many entries in the list */
Tcl_HashTable objTable; /* this hash table is keyed by object
* index and is used to store information
* about references to this object. */
ProcBodyInfo** infoArrayPtr; /* NULL-terminated array to pointers of
* info structs that are generated for
* each proc at the start of the post
* processing step */
Tcl_Size numCompiledBodies; /* total number of procedure bodies that
* were compiled. Not all procedure
* bodies are compiled. */
Tcl_Size numUnshares; /* total number of unshares that were
* performed. If 0, then there were no
* shared procedure bodies */
} PostProcessInfo;
/*
* The CompilerContext struct holds context for use by the compiler code. It
* contains a pointer to the PostProcessInfo, counters for various statistics,
* etc... There is one such struct per interpreter.
*
* This struct is exported for use by the compiler test package, otherwise it
* could be kept local to the writer.
*/
typedef struct CompilerContext
{
PostProcessInfo* ppi; /* post-processing context for the currently active compilation */
Tcl_Size numProcs; /* how many proc commands were seen in the compiled script */
Tcl_Size numCompiledBodies; /* how many proc bodies were compiled */
Tcl_Size numUnsharedBodies; /* how many were unshared */
Tcl_Size numUnshares; /* how many copies were made when unsharing proc bodies */
} CompilerContext;
/*
* This is the start of the signature line
*/
#define CMP_SIGNATURE_HEADER "TclPro ByteCode"
/*
* Default extension for compiled TCL files
*/
#define CMP_TC_EXTENSION ".tbc"
/*
* Name of the eval command exported by the Loader package
*/
#define CMP_EVAL_COMMAND "bceval"
/*
* Name of the proc command exported by the Loader package
*/
#define CMP_PROC_COMMAND "bcproc"
/*
* Name of the writer (compiler) and reader (loader) packages
*/
#define CMP_WRITER_PACKAGE "compiler"
#define CMP_READER_PACKAGE "tbcload"
#if USE_CATCH_WRAPPER
/*
* Marker string appended by Loader_EvalObjCmd to the errorInfo, for use by
* the catch code to strip out error info that we don't want.
*/
#define CMP_ERRORINFO_MARKER "----------####----------"
#endif
/*
* The one-letter codes for various object types.
* CMP_STRING_TYPE is an uncompressed/unencoded string,
* CMP_XSTRING_TYPE is compressed/encoded
*/
#define CMP_INT_CODE 'i'
#define CMP_DOUBLE_CODE 'd'
#define CMP_STRING_CODE 's'
#define CMP_XSTRING_CODE 'x'
#define CMP_PROCBODY_CODE 'p'
#define CMP_BOOLEAN_CODE 'b'
#define CMP_BYTECODE_CODE 'c'
/*
* The one-letter codes for the exception range types
*/
#define CMP_LOOP_EXCEPTION_RANGE 'L'
#define CMP_CATCH_EXCEPTION_RANGE 'C'
/*
* The one-letter codes for the AuxData types range types
*/
#define CMP_JUMPTABLE_INFO 'J'
#define CMP_DICTUPDATE_INFO 'D'
#define CMP_NEW_FOREACH_INFO 'f'
/*
* the following set of procedures needs to be wrapped around a DLLEXPORT
* macro setup, because they are exported by the Tbcload DLL
*/
#ifdef BUILD_tbcload
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif
/*
*---------------------------------------------------------------
* Procedures exported by the proc body object support, used internally by
* both compiler and loader.
* They are defined in the loader DLL, and exported internally to the
* compiler.
*---------------------------------------------------------------
*/
EXTERN void ProcBodyCleanupProc(Proc* procPtr);
EXTERN Tcl_Obj* ProcBodyNewObj(Proc* procPtr);
EXTERN void ProcBodyRegisterTypes(void);
/*
*----------------------------------------------------------------
* Procedures exported by cmpRead.c and cmpRPkg.c
*----------------------------------------------------------------
*/
EXTERN int TbcloadInit(Tcl_Interp* interp);
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
/*
*----------------------------------------------------------------
* Procedures exported for use by the test package
*----------------------------------------------------------------
*/
EXTERN const char* CmptestGetPackageName();
EXTERN int Cmptest_Init(Tcl_Interp* interp);
/*
*----------------------------------------------------------------
* Procedures exported by cmpWrite.c and cmpWPkg.c
*----------------------------------------------------------------
*/
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tclcompiler
#define TCL_STORAGE_CLASS DLLEXPORT
#else
#define TCL_STORAGE_CLASS DLLIMPORT
#endif
/* GetContext exported for use by Test package. */
EXTERN CompilerContext* CompilerGetContext(Tcl_Interp* interp);
EXTERN void CompilerInit(Tcl_Interp* interp);
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _CMPINT_H */