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_detag_pointer (oop)))
36 struct st_header __parent__
;
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 _ST_METHOD_SET_BITFIELD(bitfield, field, value) \
121 ((bitfield) = ((bitfield) & ~(_ST_METHOD_##field##_MASK << _ST_METHOD_##field##_SHIFT)) \
122 | (((value) & _ST_METHOD_##field##_MASK) << _ST_METHOD_##field##_SHIFT))
124 #define _ST_METHOD_GET_BITFIELD(bitfield, field) \
125 (((bitfield) >> _ST_METHOD_##field##_SHIFT) & _ST_METHOD_##field##_MASK)
129 _ST_METHOD_FLAG_BITS
= 3,
130 _ST_METHOD_ARG_BITS
= 5,
131 _ST_METHOD_TEMP_BITS
= 6,
132 _ST_METHOD_UNUSED_BITS
= 7,
133 _ST_METHOD_LARGE_BITS
= 1,
134 _ST_METHOD_INSTVAR_BITS
= 16,
135 _ST_METHOD_LITERAL_BITS
= 4,
136 _ST_METHOD_PRIMITIVE_BITS
= 8,
138 _ST_METHOD_PRIMITIVE_SHIFT
= ST_TAG_SIZE
,
139 _ST_METHOD_INSTVAR_SHIFT
= ST_TAG_SIZE
,
140 _ST_METHOD_LITERAL_SHIFT
= ST_TAG_SIZE
,
141 _ST_METHOD_LARGE_SHIFT
= _ST_METHOD_PRIMITIVE_BITS
+ _ST_METHOD_PRIMITIVE_SHIFT
,
142 _ST_METHOD_UNUSED_SHIFT
= _ST_METHOD_LARGE_BITS
+ _ST_METHOD_LARGE_SHIFT
,
143 _ST_METHOD_TEMP_SHIFT
= _ST_METHOD_UNUSED_BITS
+ _ST_METHOD_UNUSED_SHIFT
,
144 _ST_METHOD_ARG_SHIFT
= _ST_METHOD_TEMP_BITS
+ _ST_METHOD_TEMP_SHIFT
,
145 _ST_METHOD_FLAG_SHIFT
= _ST_METHOD_ARG_BITS
+ _ST_METHOD_ARG_SHIFT
,
147 _ST_METHOD_PRIMITIVE_MASK
= ST_NTH_MASK (_ST_METHOD_PRIMITIVE_BITS
),
148 _ST_METHOD_LARGE_MASK
= ST_NTH_MASK (_ST_METHOD_LARGE_BITS
),
149 _ST_METHOD_INSTVAR_MASK
= ST_NTH_MASK (_ST_METHOD_INSTVAR_BITS
),
150 _ST_METHOD_LITERAL_MASK
= ST_NTH_MASK (_ST_METHOD_LITERAL_BITS
),
151 _ST_METHOD_TEMP_MASK
= ST_NTH_MASK (_ST_METHOD_TEMP_BITS
),
152 _ST_METHOD_ARG_MASK
= ST_NTH_MASK (_ST_METHOD_ARG_BITS
),
153 _ST_METHOD_FLAG_MASK
= ST_NTH_MASK (_ST_METHOD_FLAG_BITS
),
158 st_method_get_temp_count (st_oop method
)
160 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method
), TEMP
);
164 st_method_get_arg_count (st_oop method
)
166 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method
), ARG
);
170 st_method_get_large_context (st_oop method
)
172 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method
), LARGE
);
176 st_method_get_primitive_index (st_oop method
)
178 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method
), PRIMITIVE
);
181 static inline st_method_flags
182 st_method_get_flags (st_oop method
)
184 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method
), FLAG
);
188 st_method_set_flags (st_oop method
, st_method_flags flags
)
190 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method
), FLAG
, flags
);
194 st_method_set_arg_count (st_oop method
, int count
)
196 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method
), ARG
, count
);
200 st_method_set_temp_count (st_oop method
, int count
)
202 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method
), TEMP
, count
);
206 st_method_set_large_context (st_oop method
, bool is_large
)
208 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method
), LARGE
, is_large
);
212 st_method_set_primitive_index (st_oop method
, int index
)
214 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method
), PRIMITIVE
, index
);
218 st_method_set_instvar_index (st_oop method
, int index
)
220 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method
), INSTVAR
, index
);
224 st_method_set_literal_type (st_oop method
, st_method_literal_type literal_type
)
226 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method
), LITERAL
, literal_type
);
230 static inline st_uchar
*
231 st_method_bytecode_bytes (st_oop method
)
233 return st_byte_array_bytes (ST_METHOD_BYTECODE (method
));
236 #endif /* __ST_METHOD_H__ */