Remove expensive assertion checks in st-array.h
[panda.git] / src / st-method.h
blobec6d4233cb5f65b81cfafeac0e910ce24778856c
1 /*
2 * st-method.h
4 * Copyright (C) 2008 Vincent Geddes
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 #ifndef __ST_METHOD_H__
26 #define __ST_METHOD_H__
28 #include <st-types.h>
29 #include <st-object.h>
30 #include <st-array.h>
32 #define ST_METHOD(oop) ((struct st_method *) (ST_POINTER (oop)))
34 struct st_method
36 struct st_header object_header;
38 st_oop header;
39 st_oop bytecode;
40 st_oop literals;
41 st_oop selector;
44 typedef enum
46 ST_METHOD_NORMAL,
47 ST_METHOD_RETURN_RECEIVER,
48 ST_METHOD_RETURN_INSTVAR,
49 ST_METHOD_RETURN_LITERAL,
50 ST_METHOD_PRIMITIVE,
52 } st_method_flags;
54 typedef enum
56 ST_METHOD_LITERAL_NIL,
57 ST_METHOD_LITERAL_TRUE,
58 ST_METHOD_LITERAL_FALSE,
59 ST_METHOD_LITERAL_MINUS_ONE,
60 ST_METHOD_LITERAL_ZERO,
61 ST_METHOD_LITERAL_ONE,
62 ST_METHOD_LITERAL_TWO,
64 } st_method_literal_type;
66 #define ST_METHOD_HEADER(oop) (ST_METHOD (oop)->header)
67 #define ST_METHOD_LITERALS(oop) (ST_METHOD (oop)->literals)
68 #define ST_METHOD_BYTECODE(oop) (ST_METHOD (oop)->bytecode)
69 #define ST_METHOD_SELECTOR(oop) (ST_METHOD (oop)->selector)
72 * CompiledMethod Header:
74 * The header is a smi containing various bitfields.
76 * A flag bitfield in the header indicates how the method must be executed. Generally
77 * it provides various optimization hints to the interpreter. The flag bitfield
78 * is alway stored in bits 31-29. The format of the remaining bits in the header
79 * varies according to the flag value.
81 * flag (3 bits):
82 * 0 : Activate method and execute its bytecodes
83 * 1 : The method simply returns 'self'. Has no side-effects. Don't bother creating a new activation.
84 * 2 : The method simply returns an instance variable. Ditto.
85 * 3 : The method simply returns a literal. Ditto.
86 * 4 : The method performs a primitive operation.
88 * Bitfield format
90 * flag = 0:
91 * [ flag: 3 | arg_count: 5 | temp_count: 6 | unused: 7 | large_context: 1 | primitive: 8 | tag: 2 ]
93 * arg_count: number of args
94 * temp_count: number of temps
95 * stack_depth: depth of stack
96 * primitive: index of a primitive method
97 * tag: The usual smi tag
99 * flag = 1:
100 * [ flag: 3 | unused: 27 | tag: 2 ]
102 * flag = 2:
103 * header: [ flag: 3 | unused: 11 | instvar: 16 | tag: 2 ]
105 * instvar_index: Index of instvar
107 * flag = 3:
108 * header: [ flag: 3 | unused: 23 | literal: 4 | tag: 2 ]
110 * literal:
111 * nil: 0
112 * true: 1
113 * false: 2
114 * -1: 3
115 * 0: 4
116 * 1: 5
117 * 2: 6
120 #define SET_BITFIELD(bits, field, value) \
121 (((bits) & ~st_##field##_mask_aligned) | ((value & st_##field##_mask) << st_##field##_shift))
123 #define GET_BITFIELD(bits, field) \
124 (((bits) >> st_##field##_shift) & st_##field##_mask)
126 enum
128 st_flag_bits = 3,
129 st_arg_bits = 5,
130 st_temp_bits = 6,
131 st_method_unused_bits = 7,
132 st_large_bits = 1,
133 st_instvar_bits = 16,
134 st_literal_bits = 4,
135 st_primitive_bits = 8,
137 st_primitive_shift = ST_TAG_SIZE,
138 st_instvar_shift = ST_TAG_SIZE,
139 st_literal_shift = ST_TAG_SIZE,
140 st_large_shift = st_primitive_bits + st_primitive_shift,
141 st_method_unused_shift = st_large_bits + st_large_shift,
142 st_temp_shift = st_method_unused_bits + st_method_unused_shift,
143 st_arg_shift = st_temp_bits + st_temp_shift,
144 st_flag_shift = st_arg_bits + st_arg_shift,
146 st_primitive_mask = ST_NTH_MASK (st_primitive_bits),
147 st_primitive_mask_aligned = st_primitive_mask << st_primitive_shift,
149 st_large_mask = ST_NTH_MASK (st_large_bits),
150 st_large_mask_aligned = st_large_mask << st_large_shift,
152 st_instvar_mask = ST_NTH_MASK (st_instvar_bits),
153 st_instvar_mask_aligned = st_instvar_mask << st_instvar_shift,
155 st_literal_mask = ST_NTH_MASK (st_literal_bits),
156 st_literal_mask_aligned = st_literal_mask << st_literal_shift,
158 st_temp_mask = ST_NTH_MASK (st_temp_bits),
159 st_temp_mask_aligned = st_temp_mask << st_temp_shift,
161 st_arg_mask = ST_NTH_MASK (st_arg_bits),
162 st_arg_mask_aligned = st_arg_mask << st_arg_shift,
164 st_flag_mask = ST_NTH_MASK (st_flag_bits),
165 st_flag_mask_aligned = st_flag_mask << st_flag_shift,
169 static inline int
170 st_method_get_temp_count (st_oop method)
172 return GET_BITFIELD (ST_METHOD_HEADER (method), temp);
175 static inline int
176 st_method_get_arg_count (st_oop method)
178 return GET_BITFIELD (ST_METHOD_HEADER (method), arg);
181 static inline int
182 st_method_get_large_context (st_oop method)
184 return GET_BITFIELD (ST_METHOD_HEADER (method), large);
187 static inline int
188 st_method_get_primitive_index (st_oop method)
190 return GET_BITFIELD (ST_METHOD_HEADER (method), primitive);
193 static inline st_method_flags
194 st_method_get_flags (st_oop method)
196 return GET_BITFIELD (ST_METHOD_HEADER (method), flag);
199 static inline void
200 st_method_set_flags (st_oop method, st_method_flags flags)
202 ST_METHOD_HEADER (method) = SET_BITFIELD (ST_METHOD_HEADER (method), flag, flags);
205 static inline void
206 st_method_set_arg_count (st_oop method, int count)
208 ST_METHOD_HEADER (method) = SET_BITFIELD (ST_METHOD_HEADER (method), arg, count);
211 static inline void
212 st_method_set_temp_count (st_oop method, int count)
214 ST_METHOD_HEADER (method) = SET_BITFIELD (ST_METHOD_HEADER (method), temp, count);
217 static inline void
218 st_method_set_large_context (st_oop method, bool is_large)
220 ST_METHOD_HEADER (method) = SET_BITFIELD (ST_METHOD_HEADER (method), large, is_large);
223 static inline void
224 st_method_set_primitive_index (st_oop method, int index)
226 ST_METHOD_HEADER (method) = SET_BITFIELD (ST_METHOD_HEADER (method), primitive, index);
229 static inline void
230 st_method_set_instvar_index (st_oop method, int index)
232 ST_METHOD_HEADER (method) = SET_BITFIELD (ST_METHOD_HEADER (method), instvar, index);
235 static inline void
236 st_method_set_literal_type (st_oop method, st_method_literal_type literal_type)
238 ST_METHOD_HEADER (method) = SET_BITFIELD (ST_METHOD_HEADER (method), literal, literal_type);
242 static inline st_uchar *
243 st_method_bytecode_bytes (st_oop method)
245 return st_byte_array_bytes (ST_METHOD_BYTECODE (method));
248 #endif /* __ST_METHOD_H__ */