1 /******************************** -*- C -*- ****************************
2  *
3  *	Byte Code definitions.
4  *
5  *
6  ***********************************************************************/
7 
8 /***********************************************************************
9  *
10  * Copyright 1988,89,90,91,92,94,95,99,2000,2001,2002,2006,2008,2009
11  * Free Software Foundation, Inc.
12  * Written by Steve Byrne.
13  *
14  * This file is part of GNU Smalltalk.
15  *
16  * GNU Smalltalk is free software; you can redistribute it and/or modify it
17  * under the terms of the GNU General Public License as published by the Free
18  * Software Foundation; either version 2, or (at your option) any later
19  * version.
20  *
21  * Linking GNU Smalltalk statically or dynamically with other modules is
22  * making a combined work based on GNU Smalltalk.  Thus, the terms and
23  * conditions of the GNU General Public License cover the whole
24  * combination.
25  *
26  * In addition, as a special exception, the Free Software Foundation
27  * give you permission to combine GNU Smalltalk with free software
28  * programs or libraries that are released under the GNU LGPL and with
29  * independent programs running under the GNU Smalltalk virtual machine.
30  *
31  * You may copy and distribute such a system following the terms of the
32  * GNU GPL for GNU Smalltalk and the licenses of the other code
33  * concerned, provided that you include the source code of that other
34  * code when and as the GNU GPL requires distribution of source code.
35  *
36  * Note that people who make modified versions of GNU Smalltalk are not
37  * obligated to grant this special exception for their modified
38  * versions; it is their choice whether to do so.  The GNU General
39  * Public License gives permission to release a modified version without
40  * this exception; this exception also makes it possible to release a
41  * modified version which carries forward this exception.
42  *
43  * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
44  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
45  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
46  * more details.
47  *
48  * You should have received a copy of the GNU General Public License along with
49  * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
50  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
51  *
52  ***********************************************************************/
53 
54 
55 #ifndef GST_BYTE_H
56 #define GST_BYTE_H
57 
58 enum {
59   PLUS_SPECIAL = 0,
60   MINUS_SPECIAL = 1,
61   LESS_THAN_SPECIAL = 2,
62   GREATER_THAN_SPECIAL = 3,
63   LESS_EQUAL_SPECIAL = 4,
64   GREATER_EQUAL_SPECIAL = 5,
65   EQUAL_SPECIAL = 6,
66   NOT_EQUAL_SPECIAL = 7,
67   TIMES_SPECIAL = 8,
68   DIVIDE_SPECIAL = 9,
69   REMAINDER_SPECIAL = 10,
70   BIT_XOR_SPECIAL = 11,
71   BIT_SHIFT_SPECIAL = 12,
72   INTEGER_DIVIDE_SPECIAL = 13,
73   BIT_AND_SPECIAL = 14,
74   BIT_OR_SPECIAL = 15,
75 
76   AT_SPECIAL = 16,
77   AT_PUT_SPECIAL = 17,
78   SIZE_SPECIAL = 18,
79   CLASS_SPECIAL = 19,
80   IS_NIL_SPECIAL = 20,
81   NOT_NIL_SPECIAL = 21,
82   VALUE_SPECIAL = 22,
83   VALUE_COLON_SPECIAL = 23,
84   SAME_OBJECT_SPECIAL = 24,
85   JAVA_AS_INT_SPECIAL = 25,
86   JAVA_AS_LONG_SPECIAL = 26,
87 
88   NEW_COLON_SPECIAL = 32,
89   THIS_CONTEXT_SPECIAL = 33,
90 
91   SEND = 28,
92   SEND_SUPER = 29,
93   SEND_IMMEDIATE = 30,
94   SEND_SUPER_IMMEDIATE = 31,
95 
96   PUSH_TEMPORARY_VARIABLE = 32,
97   PUSH_OUTER_TEMP = 33,
98   PUSH_LIT_VARIABLE = 34,
99   PUSH_RECEIVER_VARIABLE = 35,
100   STORE_TEMPORARY_VARIABLE = 36,
101   STORE_OUTER_TEMP = 37,
102   STORE_LIT_VARIABLE = 38,
103   STORE_RECEIVER_VARIABLE = 39,
104   JUMP_BACK = 40,
105   JUMP = 41,
106   POP_JUMP_TRUE = 42,
107   POP_JUMP_FALSE = 43,
108   PUSH_INTEGER = 44,
109   PUSH_SPECIAL = 45,
110   PUSH_LIT_CONSTANT = 46,
111   POP_INTO_NEW_STACKTOP = 47,
112   POP_STACK_TOP = 48,
113   MAKE_DIRTY_BLOCK = 49,
114   RETURN_METHOD_STACK_TOP = 50,
115   RETURN_CONTEXT_STACK_TOP = 51,
116   DUP_STACK_TOP = 52,
117   EXIT_INTERPRETER = 53,
118   LINE_NUMBER_BYTECODE = 54,
119   EXT_BYTE = 55,
120   PUSH_SELF = 56,
121 
122   NIL_INDEX = 0,
123   TRUE_INDEX = TRUE_OOP_INDEX - NIL_OOP_INDEX,
124   FALSE_INDEX = FALSE_OOP_INDEX - NIL_OOP_INDEX,
125   THIS_CONTEXT_INDEX = -128,
126   RECEIVER_INDEX = -129
127 };
128 
129 enum {
130   /* Causes _gst_line_number to always emit a line number bytecode.  */
131   LN_FORCE = 1,
132 
133   /* If LN_ABSOLUTE is also set, causes _gst_line_number to emit an absolute
134      ine number and use that line number as the offset.  If not,
135      _gst_line_number will emit line numbers relatives to that line.  */
136   LN_RESET = 2,
137 
138   /* See above for description.  */
139   LN_ABSOLUTE = 4
140 };
141 
142 typedef struct bytecode_array
143 {
144   gst_uchar *base;		/* base of the byte code array */
145   gst_uchar *ptr;		/* current byte+1 of byte code array */
146   int maxLen;			/* max allocated len of byte code array */
147   int stack_depth;
148   int max_stack_depth;
149 } *bc_vector;
150 
151 extern bc_vector _gst_cur_bytecodes
152   ATTRIBUTE_HIDDEN;
153 
154 /* Add 1 to the current stack depth and adjust the maximum depth
155    accordingly.  */
156 #define INCR_STACK_DEPTH()      do {                                         \
157    if (++_gst_cur_bytecodes->stack_depth >				     \
158        _gst_cur_bytecodes->max_stack_depth)				     \
159      _gst_cur_bytecodes->max_stack_depth++;				     \
160 } while (0)
161 
162 /* Add N to the current stack depth and adjust the maximum depth
163    accordingly.  */
164 #define ADD_STACK_DEPTH(n)      do {                                         \
165   _gst_cur_bytecodes->stack_depth += (n);                             	     \
166  if (_gst_cur_bytecodes->stack_depth > _gst_cur_bytecodes->max_stack_depth)  \
167    _gst_cur_bytecodes->max_stack_depth = _gst_cur_bytecodes->stack_depth;    \
168 } while (0)
169 
170 /* Subtract N from the current stack depth.  */
171 #define SUB_STACK_DEPTH(n)      					     \
172   (assert (_gst_cur_bytecodes->stack_depth >= (n)),		             \
173    _gst_cur_bytecodes->stack_depth -= (n))
174 
175 /* Subtract N from the current stack depth.  */
176 #define GET_STACK_DEPTH()	      					     \
177   (_gst_cur_bytecodes->max_stack_depth)
178 
179 /* Allocate a new array of bytecodes.  */
180 extern void _gst_alloc_bytecodes ()
181   ATTRIBUTE_HIDDEN;
182 
183 /* Called when byte code compilation is complete, this routine returns
184    the set of byte codes that were compiled.  Since compilation is
185    complete, this routine also resets the internal state of the byte
186    code compiler in preparation for next time.  */
187 extern bc_vector _gst_get_bytecodes (void)
188   ATTRIBUTE_HIDDEN;
189 
190 /* Called to save the set of byte codes currently being compiled and
191    prepare for a new compilation of byte codes. The current set of
192    byte codes being compiled is returned for the caller to keep and to
193    later use in a _gst_restore_bytecode_array call.  */
194 extern bc_vector _gst_save_bytecode_array ()
195   ATTRIBUTE_HIDDEN;
196 
197 /* Restores the internal state of the byte code compiler so that it
198    can continue compiling byte codes into the byte code array
199    BYTECODES, which should have been returned at some previous point
200    from _gst_save_bytecode_array().  Return the TAG that was passed
201    to _gst_save_bytecode_array.  */
202 extern void _gst_restore_bytecode_array (bc_vector)
203   ATTRIBUTE_HIDDEN;
204 
205 /* This copies the byte instance variables out of the Smalltalk
206    ByteArray object, BYTEARRAYOOP, and creates a bytecodes structure
207    for it.  This is used when a method is created by Smalltalk
208    code.  */
209 extern bc_vector _gst_extract_bytecodes (OOP byteArrayOOP)
210   ATTRIBUTE_HIDDEN;
211 
212 /* This eliminates all the bytecodes in the array starting at the one
213    pointed to by HERE.  */
214 extern void _gst_truncate_bytecodes (gst_uchar * here,
215 				     bc_vector bytecodes)
216   ATTRIBUTE_HIDDEN;
217 
218 /* This compiles a LINE_NUMBER_BYTECODE if line is different from the
219    last line we compiled, or if FORCE is true.  */
220 extern void _gst_line_number (int line, int flags)
221   ATTRIBUTE_HIDDEN;
222 
223 /* This tacks the bytecode BYTE, with argument ARG, at the end of the
224    current bytecode array.  */
225 extern void _gst_compile_byte (gst_uchar byte, int arg)
226   ATTRIBUTE_HIDDEN;
227 
228 /* This tacks the contents of the BYTECODES array at the end of the
229    current bytecode array, and then frees the array.  */
230 extern void _gst_compile_and_free_bytecodes (bc_vector bytecodes)
231   ATTRIBUTE_HIDDEN;
232 
233 /* This tacks the bytes starting at FROM (included) and ending at TO
234    (excluded) at the end of the current bytecode array.  */
235 extern void _gst_compile_bytecodes (gst_uchar * from,
236 				    gst_uchar * to)
237   ATTRIBUTE_HIDDEN;
238 
239 /* This frees the BYTECODES data structure.  */
240 extern void _gst_free_bytecodes (bc_vector bytecodes)
241   ATTRIBUTE_HIDDEN;
242 
243 /* This copies the contents of the bytecode array, BYTECODES, to the
244    memory starting at DEST.  */
245 extern void _gst_copy_bytecodes (gst_uchar * dest,
246 				 bc_vector bytecodes)
247   ATTRIBUTE_HIDDEN;
248 
249 /* This prints the bytecode pointed to by BP, using IP to resolve the
250    offsets for the relative jumps.  LITERAL_VEC is used to print the
251    literals pointed to by the bytecodes.  The first line is preceded
252    by a tab character, subsequent lines are preceded by PREFIX and a
253    tab.  */
254 extern gst_uchar *_gst_print_bytecode_name (gst_uchar * bp,
255 				            int ip,
256 				            OOP * literal_vec,
257 					    const char *prefix)
258   ATTRIBUTE_HIDDEN;
259 
260 /* This prints the bytecode array, using LITERAL_VEC is used to print
261    the literals pointed to by the bytecodes.  */
262 extern void _gst_print_bytecodes (bc_vector bytecodes,
263 				  OOP * literal_vec)
264   ATTRIBUTE_HIDDEN;
265 
266 /* This returns the current number of bytecodes that have been compiled
267    (the size of the current bytecode array).  */
268 extern int _gst_current_bytecode_length (void)
269   ATTRIBUTE_HIDDEN;
270 
271 /* This returns the number of bytecdoes compiled into the BYTECODES
272    array.  */
273 extern int _gst_bytecode_length (bc_vector bytecodes)
274   ATTRIBUTE_HIDDEN;
275 
276 /* Returns the size of each bytecode, including the arguments.  */
277 #define BYTECODE_SIZE			2
278 
279 
280 #endif /* GST_BYTE_H */
281