tombagby-llvmruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,189 @@
1
+ #include "llvmruby.h"
2
+ #include "llvm/Assembly/Parser.h"
3
+ #include "llvm/Bitcode/ReaderWriter.h"
4
+ #include "llvm/Analysis/Verifier.h"
5
+ #include "llvm/Support/MemoryBuffer.h"
6
+ #include <fstream>
7
+ #include <sstream>
8
+
9
+ extern "C" {
10
+
11
+ VALUE
12
+ llvm_module_allocate(VALUE klass) {
13
+ return Data_Wrap_Struct(klass, NULL, NULL, NULL);
14
+ }
15
+
16
+ VALUE
17
+ llvm_module_initialize(VALUE self, VALUE rname) {
18
+ Check_Type(rname, T_STRING);
19
+ DATA_PTR(self) = new Module(StringValuePtr(rname));
20
+ return self;
21
+ }
22
+
23
+ VALUE
24
+ llvm_module_get_or_insert_function(VALUE self, VALUE name, VALUE rtype) {
25
+ Check_Type(name, T_STRING);
26
+ CHECK_TYPE(rtype, cLLVMFunctionType);
27
+
28
+ Module *m = LLVM_MODULE(self);
29
+ FunctionType *type = LLVM_FUNC_TYPE(rtype);
30
+ Function *f = cast<Function>(m->getOrInsertFunction(StringValuePtr(name), type));
31
+ return llvm_function_wrap(f);
32
+ }
33
+
34
+ VALUE
35
+ llvm_module_get_function(VALUE self, VALUE name) {
36
+ Check_Type(name, T_STRING);
37
+ Module *m = LLVM_MODULE(self);
38
+ Function *f = m->getFunction(StringValuePtr(name));
39
+ return llvm_function_wrap(f);
40
+ }
41
+
42
+ VALUE
43
+ llvm_module_global_variable(VALUE self, VALUE rtype, VALUE rinitializer) {
44
+ Module *m = LLVM_MODULE(self);
45
+ Type *type = LLVM_TYPE(rtype);
46
+ Constant *initializer = (Constant*)DATA_PTR(rinitializer);
47
+ GlobalVariable *gv = new GlobalVariable(type, true, GlobalValue::InternalLinkage, initializer, "", m);
48
+ return llvm_value_wrap(gv);
49
+ }
50
+
51
+
52
+ VALUE
53
+ llvm_module_inspect(VALUE self) {
54
+ Module *m = LLVM_MODULE(self);
55
+ std::ostringstream strstrm;
56
+ strstrm << *m;
57
+ return rb_str_new2(strstrm.str().c_str());
58
+ }
59
+
60
+ VALUE
61
+ llvm_pass_manager_allocate(VALUE klass) {
62
+ return Data_Wrap_Struct(klass, NULL, NULL, NULL);
63
+ }
64
+
65
+ VALUE
66
+ llvm_pass_manager_initialize(VALUE self) {
67
+ PassManager *pm = new PassManager;
68
+ DATA_PTR(self) = pm;
69
+ return self;
70
+ }
71
+
72
+ VALUE
73
+ llvm_pass_manager_run(VALUE self, VALUE module) {
74
+ PassManager *pm = (PassManager*) DATA_PTR(self);
75
+ Module *m = LLVM_MODULE(module);
76
+
77
+ pm->add(new TargetData(m));
78
+ pm->add(createVerifierPass());
79
+ pm->add(createLowerSetJmpPass());
80
+ pm->add(createRaiseAllocationsPass());
81
+ pm->add(createCFGSimplificationPass());
82
+ pm->add(createPromoteMemoryToRegisterPass());
83
+ pm->add(createGlobalOptimizerPass());
84
+ pm->add(createGlobalDCEPass());
85
+ pm->add(createFunctionInliningPass());
86
+
87
+ pm->run(*m);
88
+ return Qtrue;
89
+ }
90
+
91
+ static ExecutionEngine *EE = NULL;
92
+
93
+ VALUE
94
+ llvm_execution_engine_get(VALUE klass, VALUE module) {
95
+ CHECK_TYPE(module, cLLVMModule);
96
+
97
+ Module *m = LLVM_MODULE(module);
98
+ ExistingModuleProvider *MP = new ExistingModuleProvider(m);
99
+
100
+ if(EE == NULL) {
101
+ EE = ExecutionEngine::create(MP, false);
102
+ } else {
103
+ EE->addModuleProvider(MP);
104
+ }
105
+
106
+ return Qtrue;
107
+ }
108
+
109
+ VALUE
110
+ llvm_module_external_function(VALUE self, VALUE name, VALUE type) {
111
+ Check_Type(name, T_STRING);
112
+ CHECK_TYPE(type, cLLVMFunctionType);
113
+
114
+ Module *module = LLVM_MODULE(self);
115
+ Function *f = Function::Create(
116
+ LLVM_FUNC_TYPE(type),
117
+ Function::ExternalLinkage,
118
+ StringValuePtr(name),
119
+ module
120
+ );
121
+ return Data_Wrap_Struct(cLLVMFunction, NULL, NULL, f);
122
+ }
123
+
124
+ VALUE
125
+ llvm_module_read_assembly(VALUE self, VALUE assembly) {
126
+ Check_Type(assembly, T_STRING);
127
+
128
+ ParseError e;
129
+ Module *module = ParseAssemblyString(
130
+ StringValuePtr(assembly),
131
+ LLVM_MODULE(self),
132
+ &e
133
+ );
134
+ //TODO How do we handle errors?
135
+ return Data_Wrap_Struct(cLLVMModule, NULL, NULL, module);
136
+ }
137
+
138
+ VALUE
139
+ llvm_module_read_bitcode(VALUE self, VALUE bitcode) {
140
+ Check_Type(bitcode, T_STRING);
141
+
142
+ MemoryBuffer *buf = MemoryBuffer::getMemBufferCopy(RSTRING(bitcode)->ptr,RSTRING(bitcode)->ptr+RSTRING(bitcode)->len);
143
+ Module *module = ParseBitcodeFile(buf);
144
+ delete buf;
145
+ return Data_Wrap_Struct(cLLVMModule, NULL, NULL, module);
146
+ }
147
+
148
+
149
+ VALUE
150
+ llvm_module_write_bitcode(VALUE self, VALUE file_name) {
151
+ Check_Type(file_name, T_STRING);
152
+
153
+ // Don't really know how to handle c++ streams well,
154
+ // dumping all into string buffer and then saving
155
+ std::ofstream file;
156
+ file.open(StringValuePtr(file_name));
157
+ WriteBitcodeToFile(LLVM_MODULE(self), file); // Convert value into a string.
158
+ return Qtrue;
159
+ }
160
+
161
+ VALUE
162
+ llvm_execution_engine_run_function(int argc, VALUE *argv, VALUE klass) {
163
+ if(argc < 1) { rb_raise(rb_eArgError, "Expected at least one argument"); }
164
+ CHECK_TYPE(argv[0], cLLVMFunction);
165
+ Function *func = LLVM_FUNCTION(argv[0]);
166
+
167
+ // Using run function is much slower than getting C function pointer
168
+ // and calling that, but it lets us pass in arbitrary numbers of
169
+ // arguments easily for now, which is nice
170
+ std::vector<GenericValue> arg_values;
171
+ for(int i = 1; i < argc; ++i) {
172
+ GenericValue arg_val;
173
+ arg_val.IntVal = APInt(sizeof(long)*8, argv[i]);
174
+ arg_values.push_back(arg_val);
175
+ }
176
+
177
+ GenericValue v = EE->runFunction(func, arg_values);
178
+ VALUE val = v.IntVal.getZExtValue();
179
+ return val;
180
+ }
181
+
182
+ /* For tests: assume no args, return uncoverted int and turn it into fixnum */
183
+ VALUE llvm_execution_engine_run_autoconvert(VALUE klass, VALUE func) {
184
+ std::vector<GenericValue> args;
185
+ GenericValue v = EE->runFunction(LLVM_FUNCTION(func), args);
186
+ VALUE val = INT2NUM(v.IntVal.getZExtValue());
187
+ return val;
188
+ }
189
+ }
@@ -0,0 +1,128 @@
1
+ #include "llvmruby.h"
2
+
3
+ extern "C" {
4
+ VALUE
5
+ llvm_value_wrap(Value* v) {
6
+ return Data_Wrap_Struct(cLLVMValue, NULL, NULL, v);
7
+ }
8
+
9
+ VALUE
10
+ llvm_value_get_name(VALUE self) {
11
+ Value *v = LLVM_VAL(self);
12
+ std::string name = v->getName();
13
+ return rb_str_new2(name.c_str());
14
+ }
15
+
16
+ VALUE
17
+ llvm_value_get_constant(VALUE self, VALUE type, VALUE v) {
18
+ return llvm_value_wrap(ConstantInt::get(LLVM_TYPE(type), FIX2INT(v)));
19
+ }
20
+
21
+ VALUE
22
+ llvm_value_get_float_constant(VALUE self, VALUE v) {
23
+ return llvm_value_wrap(ConstantFP::get(Type::FloatTy, RFLOAT(v)->value));
24
+ }
25
+
26
+ VALUE
27
+ llvm_value_get_double_constant(VALUE self, VALUE v) {
28
+ return llvm_value_wrap(ConstantFP::get(Type::DoubleTy, RFLOAT(v)->value));
29
+ }
30
+
31
+ VALUE
32
+ llvm_value_get_struct_constant(int argc, VALUE *argv, VALUE self) {
33
+ StructType *t = (StructType*)DATA_PTR(argv[0]);
34
+ std::vector<Constant*> vals;
35
+
36
+ for(int i = 1; i < argc; ++i) {
37
+ Constant *c = (Constant*)DATA_PTR(argv[i]);
38
+ vals.push_back(c);
39
+ }
40
+ return llvm_value_wrap(ConstantStruct::get(t, vals));
41
+ }
42
+
43
+ VALUE
44
+ llvm_value_get_immediate_constant(VALUE self, VALUE v) {
45
+ const IntegerType* type;
46
+ if(sizeof(VALUE) == 4) {
47
+ type = Type::Int32Ty;
48
+ } else {
49
+ type = Type::Int64Ty;
50
+ }
51
+ return llvm_value_wrap(ConstantInt::get(type, (long)v));
52
+ }
53
+
54
+ VALUE
55
+ llvm_type_pointer(VALUE self, VALUE rtype) {
56
+ Type *type;
57
+ Data_Get_Struct(rtype, Type, type);
58
+ Type* ptr_type = PointerType::getUnqual(type);
59
+ return Data_Wrap_Struct(cLLVMPointerType, NULL, NULL, ptr_type);
60
+ }
61
+
62
+ VALUE
63
+ llvm_type_struct(VALUE self, VALUE rtypes, VALUE rpacked) {
64
+ std::vector<const Type*> types;
65
+
66
+ for(int i = 0; i < RARRAY_LEN(rtypes); ++i) {
67
+ VALUE v = RARRAY_PTR(rtypes)[i];
68
+ const Type *t;
69
+ Data_Get_Struct(v, Type, t);
70
+ types.push_back(t);
71
+ }
72
+ StructType *s = StructType::get(types);
73
+ return Data_Wrap_Struct(cLLVMStructType, NULL, NULL, s);
74
+ }
75
+
76
+ VALUE
77
+ llvm_type_array(VALUE self, VALUE rtype, VALUE size) {
78
+ Type *type;
79
+ Data_Get_Struct(rtype, Type, type);
80
+ type = ArrayType::get(type, FIX2INT(size));
81
+ return Data_Wrap_Struct(cLLVMArrayType, NULL, NULL, type);
82
+ }
83
+
84
+ VALUE
85
+ llvm_type_vector(VALUE self, VALUE rtype, VALUE size) {
86
+ Type *type;
87
+ Data_Get_Struct(rtype, Type, type);
88
+ type = VectorType::get(type, FIX2INT(size));
89
+ return Data_Wrap_Struct(cLLVMVectorType, NULL, NULL, type);
90
+ }
91
+
92
+ VALUE
93
+ llvm_type_function(int argc, VALUE *argv, VALUE self) {
94
+ VALUE rret_type, rarg_types, var_args;
95
+
96
+ rb_scan_args(argc, argv, "21", &rret_type, &rarg_types, &var_args);
97
+
98
+ std::vector<const Type*> arg_types;
99
+ for(int i = 0; i < RARRAY_LEN(rarg_types); ++i) {
100
+ VALUE v = RARRAY_PTR(rarg_types)[i];
101
+ arg_types.push_back(LLVM_TYPE(v));
102
+ }
103
+ const Type *ret_type = LLVM_TYPE(rret_type);
104
+ FunctionType *ftype = FunctionType::get(ret_type, arg_types, RTEST(var_args));
105
+ return Data_Wrap_Struct(cLLVMFunctionType, NULL, NULL, ftype);
106
+ }
107
+
108
+ void init_types() {
109
+ rb_define_const(cLLVMType, "Int1Ty", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<IntegerType*>(Type::Int1Ty)));
110
+ rb_define_const(cLLVMType, "Int8Ty", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<IntegerType*>(Type::Int8Ty)));
111
+ rb_define_const(cLLVMType, "Int16Ty", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<IntegerType*>(Type::Int16Ty)));
112
+ rb_define_const(cLLVMType, "Int32Ty", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<IntegerType*>(Type::Int32Ty)));
113
+ rb_define_const(cLLVMType, "Int64Ty", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<IntegerType*>(Type::Int64Ty)));
114
+ rb_define_const(cLLVMType, "VoidTy", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<Type*>(Type::VoidTy)));
115
+ rb_define_const(cLLVMType, "LabelTy", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<Type*>(Type::LabelTy)));
116
+ rb_define_const(cLLVMType, "FloatTy", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<Type*>(Type::FloatTy)));
117
+ rb_define_const(cLLVMType, "DoubleTy", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<Type*>(Type::DoubleTy)));
118
+
119
+ // Figure out details of the target machine
120
+ const IntegerType *machine_word_type;
121
+ if(sizeof(void*) == 4) {
122
+ machine_word_type = Type::Int32Ty;
123
+ } else {
124
+ machine_word_type = Type::Int64Ty;
125
+ }
126
+ rb_define_const(cLLVMRuby, "MACHINE_WORD", Data_Wrap_Struct(cLLVMType, NULL, NULL, const_cast<IntegerType*>(machine_word_type)));
127
+ }
128
+ }
data/ext/llvmruby.c ADDED
@@ -0,0 +1,214 @@
1
+ #include "ruby.h"
2
+
3
+ VALUE cLLVMRuby = Qnil;
4
+ VALUE cLLVMValue = Qnil;
5
+ VALUE cLLVMModule = Qnil;
6
+ VALUE cLLVMFunction = Qnil;
7
+ VALUE cLLVMBasicBlock = Qnil;
8
+ VALUE cLLVMBuilder = Qnil;
9
+ VALUE cLLVMType = Qnil;
10
+ VALUE cLLVMPointerType = Qnil;
11
+ VALUE cLLVMStructType = Qnil;
12
+ VALUE cLLVMArrayType = Qnil;
13
+ VALUE cLLVMVectorType = Qnil;
14
+ VALUE cLLVMFunctionType = Qnil;
15
+ VALUE cLLVMInstruction = Qnil;
16
+ VALUE cLLVMSwitchInst = Qnil;
17
+ VALUE cLLVMPhi = Qnil;
18
+ VALUE cLLVMBinaryOps = Qnil;
19
+ VALUE cLLVMPassManager = Qnil;
20
+ VALUE cLLVMExecutionEngine = Qnil;
21
+
22
+ void init_types();
23
+ VALUE llvm_type_pointer(VALUE, VALUE);
24
+ VALUE llvm_type_struct(VALUE, VALUE, VALUE);
25
+ VALUE llvm_type_array(VALUE, VALUE, VALUE);
26
+ VALUE llvm_type_vector(VALUE, VALUE, VALUE);
27
+ VALUE llvm_type_function2(VALUE, VALUE);
28
+ VALUE llvm_type_function(VALUE, VALUE, VALUE);
29
+
30
+ void init_instructions();
31
+
32
+ VALUE llvm_module_allocate(VALUE);
33
+ VALUE llvm_module_initialize(VALUE);
34
+ VALUE llvm_module_get_or_insert_function(VALUE, VALUE);
35
+ VALUE llvm_module_get_function(VALUE, VALUE);
36
+ VALUE llvm_module_global_variable(VALUE, VALUE, VALUE);
37
+ VALUE llvm_module_external_function(VALUE, VALUE, VALUE);
38
+ VALUE llvm_module_read_assembly(VALUE, VALUE);
39
+ VALUE llvm_module_read_bitcode(VALUE, VALUE);
40
+ VALUE llvm_module_write_bitcode(VALUE, VALUE);
41
+ VALUE llvm_module_inspect(VALUE);
42
+
43
+ VALUE llvm_function_allocate(VALUE);
44
+ VALUE llvm_function_create_block(VALUE);
45
+ VALUE llvm_function_arguments(VALUE);
46
+ VALUE llvm_function_inspect(VALUE);
47
+ VALUE llvm_function_get_basic_block_list(VALUE);
48
+
49
+ VALUE llvm_basic_block_builder(VALUE);
50
+ VALUE llvm_basic_block_size(VALUE);
51
+ VALUE llvm_basic_block_get_instruction_list(VALUE);
52
+
53
+ VALUE llvm_instruction_inspect(VALUE);
54
+ VALUE llvm_instruction_get_opcode_name(VALUE);
55
+
56
+ VALUE llvm_switch_inst_get_default_dest(VALUE);
57
+ VALUE llvm_switch_inst_get_num_cases(VALUE);
58
+ VALUE llvm_switch_inst_add_case(VALUE, VALUE, VALUE);
59
+
60
+ VALUE llvm_builder_set_insert_point(VALUE, VALUE);
61
+ VALUE llvm_builder_bin_op(VALUE, VALUE, VALUE, VALUE);
62
+ VALUE llvm_builder_phi(VALUE, VALUE);
63
+ VALUE llvm_builder_return(VALUE, VALUE);
64
+ VALUE llvm_builder_br(VALUE, VALUE);
65
+ VALUE llvm_builder_cond_br(VALUE, VALUE, VALUE, VALUE);
66
+ VALUE llvm_builder_switch(VALUE, VALUE, VALUE);
67
+
68
+ VALUE llvm_builder_malloc(VALUE, VALUE, VALUE);
69
+ VALUE llvm_builder_free(VALUE, VALUE);
70
+ VALUE llvm_builder_alloca(VALUE, VALUE, VALUE);
71
+ VALUE llvm_builder_load(VALUE, VALUE);
72
+ VALUE llvm_builder_store(VALUE, VALUE, VALUE);
73
+ VALUE llvm_builder_icmp(VALUE, VALUE, VALUE, VALUE);
74
+ VALUE llvm_builder_fcmp(VALUE, VALUE, VALUE, VALUE);
75
+ VALUE llvm_builder_gep(VALUE, VALUE, VALUE);
76
+ VALUE llvm_builder_struct_gep(VALUE, VALUE, VALUE);
77
+ VALUE llvm_builder_cast(VALUE, VALUE, VALUE, VALUE);
78
+ VALUE llvm_builder_int_to_ptr(VALUE, VALUE, VALUE);
79
+ VALUE llvm_builder_int_cast(VALUE, VALUE, VALUE);
80
+ VALUE llvm_builder_call(int, VALUE*, VALUE);
81
+ VALUE llvm_builder_insert_element(VALUE, VALUE, VALUE, VALUE);
82
+ VALUE llvm_builder_extract_element(VALUE, VALUE, VALUE);
83
+ VALUE llvm_builder_get_global(VALUE);
84
+ VALUE llvm_builder_create_global_string_ptr(VALUE);
85
+
86
+ VALUE llvm_value_get_constant(VALUE);
87
+ VALUE llvm_value_get_float_constant(VALUE);
88
+ VALUE llvm_value_get_double_constant(VALUE);
89
+ VALUE llvm_value_get_immediate_constant(VALUE);
90
+ VALUE llvm_value_get_struct_constant(int, VALUE*, VALUE);
91
+ VALUE llvm_value_get_name(VALUE);
92
+
93
+
94
+ VALUE llvm_phi_add_incoming(VALUE, VALUE, VALUE);
95
+
96
+ VALUE llvm_pass_manager_allocate(VALUE);
97
+ VALUE llvm_pass_manager_initialize(VALUE);
98
+ VALUE llvm_pass_manager_run(VALUE, VALUE);
99
+ VALUE llvm_execution_engine_get(VALUE, VALUE);
100
+ VALUE llvm_execution_engine_run_function(int, VALUE*, VALUE);
101
+ VALUE llvm_execution_engine_run_autoconvert(VALUE, VALUE);
102
+
103
+ void Init_llvmruby() {
104
+ cLLVMRuby = rb_define_module("LLVM");
105
+
106
+ cLLVMType = rb_define_class_under(cLLVMRuby, "Type", rb_cObject);
107
+ cLLVMPointerType = rb_define_class_under(cLLVMRuby, "PointerType", cLLVMType);
108
+ cLLVMStructType = rb_define_class_under(cLLVMRuby, "StructType", cLLVMType);
109
+ cLLVMArrayType = rb_define_class_under(cLLVMRuby, "ArrayType", cLLVMType);
110
+ cLLVMVectorType = rb_define_class_under(cLLVMRuby, "VectorType", cLLVMType);
111
+ cLLVMFunctionType = rb_define_class_under(cLLVMRuby, "FunctionType", cLLVMType);
112
+
113
+ cLLVMValue = rb_define_class_under(cLLVMRuby, "Value", rb_cObject);
114
+ cLLVMModule = rb_define_class_under(cLLVMRuby, "Module", rb_cObject);
115
+ cLLVMFunction = rb_define_class_under(cLLVMRuby, "Function", rb_cObject);
116
+ cLLVMBasicBlock = rb_define_class_under(cLLVMRuby, "BasicBlock", cLLVMValue);
117
+ cLLVMBuilder = rb_define_class_under(cLLVMRuby, "Builder", rb_cObject);
118
+
119
+ cLLVMInstruction = rb_define_class_under(cLLVMRuby, "Instruction", rb_cObject);
120
+ cLLVMSwitchInst = rb_define_class_under(cLLVMRuby, "SwitchInst", cLLVMInstruction);
121
+ cLLVMBinaryOps = rb_define_class_under(cLLVMInstruction, "BinaryOps", rb_cObject);
122
+ cLLVMPhi = rb_define_class_under(cLLVMRuby, "Phi", cLLVMValue);
123
+
124
+ cLLVMPassManager = rb_define_class_under(cLLVMRuby, "PassManager", rb_cObject);
125
+ cLLVMExecutionEngine = rb_define_class_under(cLLVMRuby, "ExecutionEngine", rb_cObject);
126
+
127
+ init_types();
128
+ rb_define_module_function(cLLVMType, "pointer", llvm_type_pointer, 1);
129
+ rb_define_module_function(cLLVMType, "struct", llvm_type_struct, 1);
130
+ rb_define_module_function(cLLVMType, "array", llvm_type_array, 2);
131
+ rb_define_module_function(cLLVMType, "vector", llvm_type_vector, 2);
132
+ rb_define_module_function(cLLVMType, "function", llvm_type_function, -1);
133
+
134
+ rb_define_module_function(cLLVMValue, "get_constant", llvm_value_get_constant, 2);
135
+ rb_define_module_function(cLLVMValue, "get_float_constant", llvm_value_get_float_constant, 1);
136
+ rb_define_module_function(cLLVMValue, "get_double_constant", llvm_value_get_double_constant, 1);
137
+ rb_define_module_function(cLLVMValue, "get_immediate_constant", llvm_value_get_immediate_constant, 1);
138
+ rb_define_module_function(cLLVMValue, "get_struct_constant", llvm_value_get_struct_constant, -1);
139
+ rb_define_method(cLLVMValue, "get_name", llvm_value_get_name, 0);
140
+
141
+ init_instructions();
142
+
143
+ rb_define_alloc_func(cLLVMModule, llvm_module_allocate);
144
+ rb_define_module_function(cLLVMModule, "read_assembly", llvm_module_read_assembly, 1);
145
+ rb_define_module_function(cLLVMModule, "read_bitcode", llvm_module_read_bitcode, 1);
146
+ rb_define_method(cLLVMModule, "initialize", llvm_module_initialize, 1);
147
+ rb_define_method(cLLVMModule, "get_or_insert_function", llvm_module_get_or_insert_function, 2);
148
+ rb_define_method(cLLVMModule, "get_function", llvm_module_get_function, 1);
149
+ rb_define_method(cLLVMModule, "global_variable", llvm_module_global_variable, 2);
150
+ rb_define_method(cLLVMModule, "external_function", llvm_module_external_function, 2);
151
+ rb_define_method(cLLVMModule, "write_bitcode", llvm_module_write_bitcode, 1);
152
+ rb_define_method(cLLVMModule, "inspect", llvm_module_inspect, 0);
153
+
154
+ rb_define_method(cLLVMFunction, "create_block", llvm_function_create_block, 0);
155
+ rb_define_method(cLLVMFunction, "arguments", llvm_function_arguments, 0);
156
+ rb_define_method(cLLVMFunction, "inspect", llvm_function_inspect, 0);
157
+ rb_define_method(cLLVMFunction, "get_basic_block_list", llvm_function_get_basic_block_list, 0);
158
+
159
+ rb_define_method(cLLVMBasicBlock, "builder", llvm_basic_block_builder, 0);
160
+ rb_define_method(cLLVMBasicBlock, "size", llvm_basic_block_size, 0);
161
+ rb_define_method(cLLVMBasicBlock, "get_instruction_list", llvm_basic_block_get_instruction_list, 0);
162
+
163
+ rb_define_method(cLLVMInstruction, "inspect", llvm_instruction_inspect, 0);
164
+ rb_define_method(cLLVMInstruction, "get_opcode_name", llvm_instruction_get_opcode_name, 0);
165
+
166
+ rb_define_method(cLLVMSwitchInst, "get_default_dest", llvm_switch_inst_get_default_dest, 0);
167
+ rb_define_method(cLLVMSwitchInst, "get_num_cases", llvm_switch_inst_get_num_cases, 0);
168
+ rb_define_method(cLLVMSwitchInst, "add_case", llvm_switch_inst_add_case, 2);
169
+
170
+ rb_define_method(cLLVMBuilder, "set_insert_point", llvm_builder_set_insert_point, 1);
171
+ rb_define_method(cLLVMBuilder, "bin_op", llvm_builder_bin_op, 3);
172
+ rb_define_method(cLLVMBuilder, "phi", llvm_builder_phi, 1);
173
+ rb_define_method(cLLVMBuilder, "return", llvm_builder_return, 1);
174
+ rb_define_method(cLLVMBuilder, "br", llvm_builder_br, 1);
175
+ rb_define_method(cLLVMBuilder, "cond_br", llvm_builder_cond_br, 3);
176
+ rb_define_method(cLLVMBuilder, "switch", llvm_builder_switch, 2);
177
+ rb_define_method(cLLVMBuilder, "malloc", llvm_builder_malloc, 2);
178
+ rb_define_method(cLLVMBuilder, "free", llvm_builder_free, 1);
179
+ rb_define_method(cLLVMBuilder, "alloca", llvm_builder_alloca, 2);
180
+ rb_define_method(cLLVMBuilder, "load", llvm_builder_load, 1);
181
+ rb_define_method(cLLVMBuilder, "store", llvm_builder_store, 2);
182
+ rb_define_method(cLLVMBuilder, "icmp", llvm_builder_icmp, 3);
183
+ rb_define_method(cLLVMBuilder, "fcmp", llvm_builder_fcmp, 3);
184
+
185
+ rb_define_method(cLLVMBuilder, "gep", llvm_builder_gep, 2);
186
+ rb_define_method(cLLVMBuilder, "struct_gep", llvm_builder_struct_gep, 2);
187
+ rb_define_method(cLLVMBuilder, "cast", llvm_builder_cast, 3);
188
+ rb_define_method(cLLVMBuilder, "int_to_ptr", llvm_builder_int_to_ptr, 2);
189
+ rb_define_method(cLLVMBuilder, "int_cast", llvm_builder_int_cast, 3);
190
+ rb_define_method(cLLVMBuilder, "call", llvm_builder_call, -1);
191
+ rb_define_method(cLLVMBuilder, "insert_element", llvm_builder_insert_element, 3);
192
+ rb_define_method(cLLVMBuilder, "extract_element", llvm_builder_extract_element, 2);
193
+ rb_define_method(cLLVMBuilder, "get_global", llvm_builder_get_global, 0);
194
+ rb_define_method(cLLVMBuilder, "create_global_string_ptr", llvm_builder_create_global_string_ptr, 1);
195
+
196
+ rb_define_method(cLLVMPhi, "add_incoming", llvm_phi_add_incoming, 2);
197
+
198
+ rb_define_alloc_func(cLLVMModule, llvm_pass_manager_allocate);
199
+ rb_define_method(cLLVMPassManager, "initialize", llvm_pass_manager_initialize, 0);
200
+ rb_define_method(cLLVMPassManager, "run", llvm_pass_manager_run, 1);
201
+
202
+ rb_define_module_function(cLLVMExecutionEngine, "get", llvm_execution_engine_get, 1);
203
+ rb_define_module_function(cLLVMExecutionEngine, "run_function", llvm_execution_engine_run_function, -1);
204
+ rb_define_module_function(cLLVMExecutionEngine, "run_autoconvert", llvm_execution_engine_run_autoconvert, 1);
205
+
206
+ /*
207
+ printf("sizeof long: %d\n", (int)sizeof(long));
208
+ printf("sizeof ptr: %d\n", (int)sizeof(long*));
209
+ printf("sizeof value: %d\n", (int)sizeof(VALUE));
210
+ printf("sizeof array: %d\n", (int)sizeof(struct RArray));
211
+ printf("sizeof int: %d\n", (int)sizeof(int));
212
+ printf("sizeof char: %d\n", (int)sizeof(char));
213
+ */
214
+ }
data/ext/llvmruby.h ADDED
@@ -0,0 +1,60 @@
1
+ #define __STDC_LIMIT_MACROS
2
+
3
+ #include "llvm/Module.h"
4
+ #include "llvm/DerivedTypes.h"
5
+ #include "llvm/Constants.h"
6
+ #include "llvm/Instructions.h"
7
+ #include "llvm/ModuleProvider.h"
8
+ #include "llvm/PassManager.h"
9
+ #include "llvm/LinkAllPasses.h"
10
+ #include "llvm/Target/TargetData.h"
11
+ #include "llvm/Transforms/Scalar.h"
12
+ #include "llvm/Analysis/Verifier.h"
13
+ #include "llvm/ExecutionEngine/JIT.h"
14
+ #include "llvm/ExecutionEngine/Interpreter.h"
15
+ #include "llvm/ExecutionEngine/GenericValue.h"
16
+ #include "llvm/Support/IRBuilder.h"
17
+ #include <iostream>
18
+ using namespace llvm;
19
+
20
+ #include "ruby.h"
21
+
22
+ extern VALUE cLLVMRuby;
23
+ extern VALUE cLLVMValue;
24
+ extern VALUE cLLVMModule;
25
+ extern VALUE cLLVMFunction;
26
+ extern VALUE cLLVMBasicBlock;
27
+ extern VALUE cLLVMBuilder;
28
+ extern VALUE cLLVMType;
29
+ extern VALUE cLLVMPointerType;
30
+ extern VALUE cLLVMStructType;
31
+ extern VALUE cLLVMArrayType;
32
+ extern VALUE cLLVMVectorType;
33
+ extern VALUE cLLVMFunctionType;
34
+ extern VALUE cLLVMInstruction;
35
+ extern VALUE cLLVMSwitchInst;
36
+ extern VALUE cLLVMBinaryOps;
37
+ extern VALUE cLLVMPhi;
38
+ extern VALUE cLLVMPassManager;
39
+
40
+ #define LLVM_VAL(obj) ((Value*)DATA_PTR(obj))
41
+ #define LLVM_TYPE(obj) ((Type*)DATA_PTR(obj))
42
+ #define LLVM_FUNC_TYPE(obj) ((FunctionType*)DATA_PTR(obj))
43
+ #define LLVM_MODULE(obj) ((Module*)DATA_PTR(obj))
44
+ #define LLVM_FUNCTION(obj) ((Function*)DATA_PTR(obj))
45
+ #define LLVM_BASIC_BLOCK(obj) ((BasicBlock*)DATA_PTR(obj))
46
+ #define LLVM_INSTRUCTION(obj) ((Instruction*)DATA_PTR(obj))
47
+ #define LLVM_PHI(obj) ((PHINode*)DATA_PTR(obj))
48
+
49
+ #define CHECK_TYPE(val, klass)\
50
+ if(CLASS_OF(val) != klass) {\
51
+ rb_raise(rb_eTypeError, "wrong argument type: %s given, expected %s", rb_obj_classname(val), rb_class2name(klass));\
52
+ }
53
+
54
+ extern "C" {
55
+ VALUE llvm_value_wrap(Value*);
56
+ VALUE llvm_function_wrap(Function*);
57
+ VALUE llvm_basic_block_wrap(BasicBlock*);
58
+ VALUE llvm_function_create_block(VALUE);
59
+ VALUE llvm_instruction_wrap(Instruction*);
60
+ }