Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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.