Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 294 lines (263 sloc) 9.202 kB
cb65416 the great schism, part I
Laurent Sansonetti authored
1 #ifndef __COMPILER_H_
2 #define __COMPILER_H_
3
4 #if defined(__cplusplus)
5
6 #define ROXOR_COMPILER_DEBUG 0
7
8 // For the dispatcher.
9 #define DISPATCH_VCALL 1
10 #define DISPATCH_SUPER 2
11 #define SPLAT_ARG_FOLLOWS 0xdeadbeef
12
13 // For defined?
14 #define DEFINED_IVAR 1
15 #define DEFINED_GVAR 2
16 #define DEFINED_CVAR 3
17 #define DEFINED_CONST 4
18 #define DEFINED_LCONST 5
19 #define DEFINED_SUPER 6
20 #define DEFINED_METHOD 7
21
22 class RoxorCompiler {
23 public:
24 static llvm::Module *module;
25 static RoxorCompiler *shared;
26
27 RoxorCompiler(const char *fname);
28 virtual ~RoxorCompiler(void) { }
29
30 Value *compile_node(NODE *node);
31
32 virtual Function *compile_main_function(NODE *node);
33 Function *compile_read_attr(ID name);
34 Function *compile_write_attr(ID name);
35 Function *compile_stub(const char *types, int argc, bool is_objc);
36 Function *compile_bs_struct_new(rb_vm_bs_boxed_t *bs_boxed);
37 Function *compile_bs_struct_writer(rb_vm_bs_boxed_t *bs_boxed,
38 int field);
39 Function *compile_ffi_function(void *stub, void *imp, int argc);
40 Function *compile_to_rval_convertor(const char *type);
41 Function *compile_to_ocval_convertor(const char *type);
42 Function *compile_objc_stub(Function *ruby_func, const char *types);
43
44 const Type *convert_type(const char *type);
45
46 protected:
47 const char *fname;
48
49 std::map<ID, Value *> lvars;
50 std::vector<ID> dvars;
51 std::map<ID, int *> ivar_slots_cache;
52 std::map<std::string, GlobalVariable *> static_strings;
53
54 #if ROXOR_COMPILER_DEBUG
55 int level;
56 # define DEBUG_LEVEL_INC() (level++)
57 # define DEBUG_LEVEL_DEC() (level--)
58 #else
59 # define DEBUG_LEVEL_INC()
60 # define DEBUG_LEVEL_DEC()
61 #endif
62
63 BasicBlock *bb;
64 BasicBlock *entry_bb;
65 ID current_mid;
66 bool current_instance_method;
67 ID self_id;
68 Value *current_self;
69 bool current_block;
70 Value *current_var_uses;
71 Value *running_block;
72 BasicBlock *begin_bb;
73 BasicBlock *rescue_bb;
74 BasicBlock *ensure_bb;
75 bool current_rescue;
76 NODE *current_block_node;
77 Function *current_block_func;
78 jmp_buf *return_from_block_jmpbuf;
79 GlobalVariable *current_opened_class;
80 bool current_module;
81 BasicBlock *current_loop_begin_bb;
82 BasicBlock *current_loop_body_bb;
83 BasicBlock *current_loop_end_bb;
84 Value *current_loop_exit_val;
85
86 Function *dispatcherFunc;
87 Function *fastEqqFunc;
88 Function *whenSplatFunc;
89 Function *prepareBlockFunc;
90 Function *pushBindingFunc;
91 Function *getBlockFunc;
92 Function *currentBlockObjectFunc;
93 Function *getConstFunc;
94 Function *setConstFunc;
95 Function *prepareMethodFunc;
96 Function *singletonClassFunc;
97 Function *defineClassFunc;
98 Function *prepareIvarSlotFunc;
99 Function *getIvarFunc;
100 Function *setIvarFunc;
101 Function *definedFunc;
102 Function *undefFunc;
103 Function *aliasFunc;
104 Function *valiasFunc;
105 Function *newHashFunc;
106 Function *toAFunc;
107 Function *toAryFunc;
108 Function *catArrayFunc;
109 Function *dupArrayFunc;
110 Function *newArrayFunc;
111 Function *newStructFunc;
112 Function *newOpaqueFunc;
113 Function *getStructFieldsFunc;
114 Function *getOpaqueDataFunc;
115 Function *getPointerPtrFunc;
116 Function *checkArityFunc;
117 Function *setStructFunc;
118 Function *newRangeFunc;
119 Function *newRegexpFunc;
120 Function *strInternFunc;
121 Function *keepVarsFunc;
122 Function *masgnGetElemBeforeSplatFunc;
123 Function *masgnGetElemAfterSplatFunc;
124 Function *masgnGetSplatFunc;
125 Function *newStringFunc;
126 Function *yieldFunc;
127 Function *gvarSetFunc;
128 Function *gvarGetFunc;
129 Function *cvarSetFunc;
130 Function *cvarGetFunc;
131 Function *currentExceptionFunc;
132 Function *popExceptionFunc;
133 Function *getSpecialFunc;
134 Function *breakFunc;
135 Function *longjmpFunc;
136 Function *setjmpFunc;
137 Function *popBrokenValue;
138
139 Constant *zeroVal;
140 Constant *oneVal;
141 Constant *twoVal;
142 Constant *nilVal;
143 Constant *trueVal;
144 Constant *falseVal;
145 Constant *undefVal;
146 Constant *splatArgFollowsVal;
147 Constant *cObject;
148 const Type *RubyObjTy;
149 const Type *RubyObjPtrTy;
150 const Type *RubyObjPtrPtrTy;
151 const Type *PtrTy;
152 const Type *PtrPtrTy;
153 const Type *IntTy;
154
155 void compile_node_error(const char *msg, NODE *node);
156
157 virtual Instruction *
158 compile_const_pointer(void *ptr, bool insert_to_bb=true) {
159 Value *ptrint = ConstantInt::get(IntTy, (long)ptr);
160 return insert_to_bb
161 ? new IntToPtrInst(ptrint, PtrTy, "", bb)
162 : new IntToPtrInst(ptrint, PtrTy, "");
163 }
164
165 Instruction *
166 compile_const_pointer_to_pointer(void *ptr, bool insert_to_bb=true) {
167 Value *ptrint = ConstantInt::get(IntTy, (long)ptr);
168 return insert_to_bb
169 ? new IntToPtrInst(ptrint, PtrPtrTy, "", bb)
170 : new IntToPtrInst(ptrint, PtrPtrTy, "");
171 }
172
173 Value *compile_protected_call(Function *func,
174 std::vector<Value *> &params);
175 void compile_dispatch_arguments(NODE *args,
176 std::vector<Value *> &arguments, int *pargc);
177 Function::ArgumentListType::iterator compile_optional_arguments(
178 Function::ArgumentListType::iterator iter, NODE *node);
179 void compile_boolean_test(Value *condVal, BasicBlock *ifTrueBB,
180 BasicBlock *ifFalseBB);
181 void compile_when_arguments(NODE *args, Value *comparedToVal,
182 BasicBlock *thenBB);
183 void compile_single_when_argument(NODE *arg, Value *comparedToVal,
184 BasicBlock *thenBB);
185 virtual void compile_prepare_method(Value *classVal, Value *sel,
186 Function *new_function, rb_vm_arity_t &arity, NODE *body);
187 Value *compile_dispatch_call(std::vector<Value *> &params);
188 Value *compile_when_splat(Value *comparedToVal, Value *splatVal);
189 Value *compile_fast_eqq_call(Value *selfVal, Value *comparedToVal);
190 Value *compile_attribute_assign(NODE *node, Value *extra_val);
191 Value *compile_block_create(NODE *node=NULL);
192 Value *compile_binding(void);
193 Value *compile_optimized_dispatch_call(SEL sel, int argc,
194 std::vector<Value *> &params);
195 Value *compile_ivar_read(ID vid);
196 Value *compile_ivar_assignment(ID vid, Value *val);
197 Value *compile_cvar_assignment(ID vid, Value *val);
198 Value *compile_gvar_assignment(struct global_entry *entry, Value *val);
199 Value *compile_constant_declaration(NODE *node, Value *val);
200 Value *compile_multiple_assignment(NODE *node, Value *val);
201 void compile_multiple_assignment_element(NODE *node, Value *val);
202 Value *compile_current_class(void);
203 Value *compile_class_path(NODE *node);
204 Value *compile_const(ID id, Value *outer);
205 Value *compile_singleton_class(Value *obj);
206 Value *compile_defined_expression(NODE *node);
207 Value *compile_dstr(NODE *node);
208 Value *compile_dvar_slot(ID name);
209 void compile_break_val(Value *val);
210 Value *compile_jump(NODE *node);
211 virtual Value *compile_mcache(SEL sel, bool super);
212 virtual Value *compile_ccache(ID id);
213 virtual Instruction *compile_sel(SEL sel, bool add_to_bb=true) {
214 return compile_const_pointer(sel, add_to_bb);
215 }
216 GlobalVariable *compile_const_global_string(const char *str);
217
218 void compile_landing_pad_header(void);
219 void compile_landing_pad_footer(void);
220 void compile_rethrow_exception(void);
221 void compile_pop_exception(void);
222 Value *compile_lvar_slot(ID name);
223 bool compile_lvars(ID *tbl);
224 Value *compile_new_struct(Value *klass, std::vector<Value *> &fields);
225 Value *compile_new_opaque(Value *klass, Value *val);
226 void compile_get_struct_fields(Value *val, Value *buf,
227 rb_vm_bs_boxed_t *bs_boxed);
228 Value *compile_get_opaque_data(Value *val, rb_vm_bs_boxed_t *bs_boxed,
229 Value *slot);
230 Value *compile_get_cptr(Value *val, const char *type, Value *slot);
231 void compile_check_arity(Value *given, Value *requested);
232 void compile_set_struct(Value *rcv, int field, Value *val);
233
234 Value *compile_conversion_to_c(const char *type, Value *val,
235 Value *slot);
236 Value *compile_conversion_to_ruby(const char *type,
237 const Type *llvm_type, Value *val);
238
239 int *get_slot_cache(ID id) {
240 if (current_block || !current_instance_method || current_module) {
241 return NULL;
242 }
243 std::map<ID, int *>::iterator iter = ivar_slots_cache.find(id);
244 if (iter == ivar_slots_cache.end()) {
245 #if ROXOR_COMPILER_DEBUG
246 printf("allocating a new slot for ivar %s\n", rb_id2name(id));
247 #endif
248 int *slot = (int *)malloc(sizeof(int));
249 *slot = -1;
250 ivar_slots_cache[id] = slot;
251 return slot;
252 }
253 return iter->second;
254 }
255
256 ICmpInst *is_value_a_fixnum(Value *val);
257 void compile_ivar_slots(Value *klass, BasicBlock::InstListType &list,
258 BasicBlock::InstListType::iterator iter);
259 bool unbox_ruby_constant(Value *val, VALUE *rval);
260 SEL mid_to_sel(ID mid, int arity);
261 };
262
263 class RoxorAOTCompiler : public RoxorCompiler {
264 public:
265 RoxorAOTCompiler(const char *fname) : RoxorCompiler(fname) { }
266
267 Function *compile_main_function(NODE *node);
268
269 private:
270 std::map<SEL, GlobalVariable *> mcaches;
271 std::map<ID, GlobalVariable *> ccaches;
272 std::map<SEL, GlobalVariable *> sels;
273
274 Value *compile_mcache(SEL sel, bool super);
275 Value *compile_ccache(ID id);
276 Instruction *compile_sel(SEL sel, bool add_to_bb=true);
277 void compile_prepare_method(Value *classVal, Value *sel,
278 Function *new_function, rb_vm_arity_t &arity, NODE *body);
279
280 Instruction *
281 compile_const_pointer(void *ptr, bool insert_to_bb=true) {
282 if (ptr == NULL) {
283 return RoxorCompiler::compile_const_pointer(ptr, insert_to_bb);
284 }
285 printf("compile_const_pointer() called with a non-NULL pointer " \
286 "on the AOT compiler - leaving the ship!\n");
287 abort();
288 }
289 };
290
291 #endif /* __cplusplus */
292
293 #endif /* __COMPILER_H_ */
Something went wrong with that request. Please try again.