Removed the notion of a "large" context. For simplicity, all contexts
[panda.git] / src / st-method.h
blob388317216ea817dd42ecb438009501f6576f6869
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_detag_pointer (oop)))
34 struct st_method
36 struct st_header __parent__;
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 _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)
127 enum
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),
157 static inline int
158 st_method_get_temp_count (st_oop method)
160 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method), TEMP);
163 static inline int
164 st_method_get_arg_count (st_oop method)
166 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method), ARG);
169 static inline int
170 st_method_get_large_context (st_oop method)
172 return _ST_METHOD_GET_BITFIELD (ST_METHOD_HEADER (method), LARGE);
175 static inline int
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);
187 static inline void
188 st_method_set_flags (st_oop method, st_method_flags flags)
190 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method), FLAG, flags);
193 static inline void
194 st_method_set_arg_count (st_oop method, int count)
196 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method), ARG, count);
199 static inline void
200 st_method_set_temp_count (st_oop method, int count)
202 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method), TEMP, count);
205 static inline void
206 st_method_set_large_context (st_oop method, bool is_large)
208 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method), LARGE, is_large);
211 static inline void
212 st_method_set_primitive_index (st_oop method, int index)
214 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method), PRIMITIVE, index);
217 static inline void
218 st_method_set_instvar_index (st_oop method, int index)
220 _ST_METHOD_SET_BITFIELD (ST_METHOD_HEADER (method), INSTVAR, index);
223 static inline void
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__ */