summaryrefslogtreecommitdiffstats
path: root/generic/tclAssembly.h
blob: c950dd8ea490a839b24bdde9c0a48340b42b5966 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef _TCL_ASSEMBLY
#define _TCL_ASSEMBLY 1

#include "tclCompile.h"

/* 
 * Structure that defines a basic block - a linear sequence of bytecode
 * instructions with no jumps in or out.
 */

typedef struct BasicBlock {

    int startOffset;		/* Instruction offset of the start of 
				 * the block */
    int startLine;		/* Line number in the input script of the
				 * instruction at the  start of the block */
    int jumpLine;	        /* Line number in the input script of the
				 * 'jump' instruction that ends the block,
				 * or -1 if there is no jump */
    int may_fall_thru;      	/* Flag == 1 if control passes from this
				 * block to its successor. */
    int visited;		/* Flag==1 if this block has been visited
				 * in the stack checker*/
    struct BasicBlock* predecessor;	
				/* Predecessor of this block in the
				 * spanning tree */
    struct BasicBlock * successor1;
				/* BasicBlock structure of the following 
				 * block:  NULL at the end of the bytecode 
				 * sequence or if the block ends in an
				 * unconditional jump */ 
    Tcl_Obj * jumpTarget;	/* Jump target label if the jump target 
				 * is unresolved */
    
    int initialStackDepth;	/* Absolute stack depth on entry */
    int minStackDepth;		/* Low-water relative stack depth */
    int maxStackDepth; 		/* High-water relative stack depth */
    int finalStackDepth;	/* Relative stack depth on exit */

} BasicBlock;

/* Source instruction type recognized by the assembler */

typedef enum TalInstType {

    ASSEM_1BYTE,    /* Fixed arity, 1-byte instruction */
    ASSEM_BOOL,	    /* One Boolean operand */
    ASSEM_BOOL_LVT4,/* One Boolean, one 4-byte LVT ref. */
    ASSEM_CONCAT1,  /* 1-byte unsigned-integer operand count, must be 
		     * strictly positive, consumes N, produces 1 */
    ASSEM_EVAL,	    /* 'eval' - evaluate a constant script (by compiling it
		     * in line with the assembly code! I love Tcl!) */
    ASSEM_INDEX,    /* 4 byte operand, integer or end-integer */
    ASSEM_INVOKE,   /* 1- or 4-byte operand count, must be strictly positive,
		     * consumes N, produces 1. */
    ASSEM_JUMP,	    /* Jump instructions */
    ASSEM_LABEL,    /* The assembly directive that defines a label */
    ASSEM_LINDEX_MULTI,
		    /* 4-byte operand count, must be strictly positive,
		     * consumes N, produces 1 */
    ASSEM_LIST,     /* 4-byte operand count, must be nonnegative, consumses N,
		     * produces 1 */
    ASSEM_LSET_FLAT,/* 4-byte operand count, must be >= 3, consumes N,
		     * produces 1 */
    ASSEM_LVT,      /* One operand that references a local variable */
    ASSEM_LVT1,     /* One 1-byte operand that references a local variable */
    ASSEM_LVT1_SINT1,
		    /* One 1-byte operand that references a local variable,
		     * one signed-integer 1-byte operand */
    ASSEM_LVT4,     /* One 4-byte operand that references a local variable */
    ASSEM_OVER,	    /* OVER: 4-byte operand count, consumes N+1, produces N+2 */
    ASSEM_PUSH,     /* one literal operand */
    ASSEM_REVERSE,  /* REVERSE: 4-byte operand count, consumes N, produces N */
    ASSEM_SINT1,    /* One 1-byte signed-integer operand (INCR_STK_IMM) */
} TalInstType;

/* Description of an instruction recognized by the assembler. */

typedef struct TalInstDesc {
    const char *name;		/* Name of instruction. */
    TalInstType instType; 	/* The type of instruction */
    int tclInstCode;		/* Instruction code. For instructions having
				 * 1- and 4-byte variables, tclInstCode is
				 * ((1byte)<<8) || (4byte) */
    int operandsConsumed;	/* Number of operands consumed by the
				 * operation, or INT_MIN if the operation
				 * is variadic */
    int operandsProduced;	/* Number of operands produced by the
				 * operation. If negative, the operation
				 * has a net stack effect of 
				 * -1-operandsProduced */
} TalInstDesc;

/* Description of a label in the assembly code */

typedef struct JumpLabel {
    int isDefined;		/* Flag == 1 if label is defined */
    int offset;			/* Offset in the code where the label starts,
				 * or head of a linked list of jump target
				 * addresses if the label is undefined */
    BasicBlock* basicBlock;	/* Basic block that begins at the label */
} JumpLabel;

/* Structure that holds the state of the assembler while generating code */

typedef struct AssembleEnv {
    CompileEnv* envPtr;		/* Compilation environment being used
				 * for code generation */
    Tcl_Parse* parsePtr;        /* Parse of the current line of source */
    Tcl_HashTable labelHash;	/* Hash table whose keys are labels and
				 * whose values are 'label' objects storing 
				 * the code offsets of the labels. */

    int cmdLine;		/* Current line number within the assembly 
				 * code */
    int* clNext;		/* Invisible continuation line for
				 * [info frame] */

    BasicBlock* head_bb;	/* First basic block in the code */
    BasicBlock* curr_bb;	/* Current basic block */

    int maxDepth;	     	/* Maximum stack depth encountered */
    int flags;			/* Compilation flags (TCL_EVAL_DIRECT) */
} AssembleEnv;

MODULE_SCOPE int TclAssembleCode(CompileEnv* compEnv, const char* codePtr,
				 int codeLen, int flags);

#endif