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
25 #ifndef __ST_METHOD_H__
26 #define __ST_METHOD_H__
29 #include <st-object.h>
32 #define ST_METHOD(oop) ((struct st_method *) (ST_POINTER (oop)))
36 struct st_header object_header
;
47 ST_METHOD_RETURN_RECEIVER
,
48 ST_METHOD_RETURN_INSTVAR
,
49 ST_METHOD_RETURN_LITERAL
,
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.
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.
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
100 * [ flag: 3 | unused: 27 | tag: 2 ]
103 * header: [ flag: 3 | unused: 11 | instvar: 16 | tag: 2 ]
105 * instvar_index: Index of instvar
108 * header: [ flag: 3 | unused: 23 | literal: 4 | tag: 2 ]
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)
131 st_method_unused_bits
= 7,
133 st_instvar_bits
= 16,
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
,
170 st_method_get_temp_count (st_oop method
)
172 return GET_BITFIELD (ST_METHOD_HEADER (method
), temp
);
176 st_method_get_arg_count (st_oop method
)
178 return GET_BITFIELD (ST_METHOD_HEADER (method
), arg
);
182 st_method_get_large_context (st_oop method
)
184 return GET_BITFIELD (ST_METHOD_HEADER (method
), large
);
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
);
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
);
206 st_method_set_arg_count (st_oop method
, int count
)
208 ST_METHOD_HEADER (method
) = SET_BITFIELD (ST_METHOD_HEADER (method
), arg
, count
);
212 st_method_set_temp_count (st_oop method
, int count
)
214 ST_METHOD_HEADER (method
) = SET_BITFIELD (ST_METHOD_HEADER (method
), temp
, count
);
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
);
224 st_method_set_primitive_index (st_oop method
, int index
)
226 ST_METHOD_HEADER (method
) = SET_BITFIELD (ST_METHOD_HEADER (method
), primitive
, index
);
230 st_method_set_instvar_index (st_oop method
, int index
)
232 ST_METHOD_HEADER (method
) = SET_BITFIELD (ST_METHOD_HEADER (method
), instvar
, index
);
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__ */