plessl-llvmruby 0.0.3
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.
- data/COPYING +21 -0
- data/README +76 -0
- data/Rakefile +31 -0
- data/ext/extconf.rb +14 -0
- data/ext/llvm_basicblock.cpp +299 -0
- data/ext/llvm_function.cpp +48 -0
- data/ext/llvm_instruction.cpp +259 -0
- data/ext/llvm_module.cpp +189 -0
- data/ext/llvm_use.cpp +9 -0
- data/ext/llvm_user.cpp +71 -0
- data/ext/llvm_value.cpp +254 -0
- data/ext/llvmruby.c +328 -0
- data/ext/llvmruby.h +73 -0
- data/lib/llvm.rb +146 -0
- data/lib/ruby_vm.rb +352 -0
- data/lib/version.rb +11 -0
- data/test/byteswap.bc +0 -0
- data/test/test_basic.rb +340 -0
- data/test/test_basic_block.rb +80 -0
- data/test/test_instructions.rb +112 -0
- data/test/test_read_bitcode.rb +38 -0
- data/test/test_ruby_vm.rb +172 -0
- data/test/test_user.rb +72 -0
- data/test/test_value.rb +63 -0
- metadata +87 -0
data/COPYING
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2008 Thomas Bagby
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
* What's LLVMRuby
|
2
|
+
|
3
|
+
LLVMRuby is a set of bindings making the LLVM compiler infrastructure
|
4
|
+
(http://llvm.org) usable from Ruby. This extention allows using LLVM
|
5
|
+
as an abstract assembler and reflects a good chunk of the LLVM class
|
6
|
+
hierarchy into Ruby. Included is an example of using this to build
|
7
|
+
a simple JIT compiler, written entirely in Ruby, which is able to
|
8
|
+
interact with the native Ruby 1.8/1.9 data types.
|
9
|
+
|
10
|
+
* How to build
|
11
|
+
|
12
|
+
You must get LLVM from svn and build it separately:
|
13
|
+
|
14
|
+
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
|
15
|
+
|
16
|
+
Make sure that you configure LLVM with PIC enabled:
|
17
|
+
|
18
|
+
$ ./configure --enable-pic
|
19
|
+
|
20
|
+
Add the llvm bin directory to your path, extconf needs to be able to find llvm-conf:
|
21
|
+
|
22
|
+
$ export PATH=$PATH:/$LLVMDIR/Release/bin
|
23
|
+
|
24
|
+
Run rake
|
25
|
+
|
26
|
+
$ rake
|
27
|
+
|
28
|
+
Run the tests (you will need Rake installed)
|
29
|
+
|
30
|
+
$ rake test
|
31
|
+
|
32
|
+
Look in test.rb to see examples of use and start messing around. The
|
33
|
+
project was recently reorganized in gem format with Ruby files in lib,
|
34
|
+
and C/CPP and extension in ext. You will need to either load the
|
35
|
+
library as a gem or make sure that both lib and ext dirs are in your
|
36
|
+
load path.
|
37
|
+
|
38
|
+
* Caveats
|
39
|
+
|
40
|
+
I created this using very latest LLVM (from svn, soon to be 2.4). Other
|
41
|
+
versions may not work. I have been trying to get the 2.3 released package
|
42
|
+
to work, only one conditional typedef is required, but it complaining about
|
43
|
+
fPIC stuff :(
|
44
|
+
|
45
|
+
I primarily develop this on my home machine which is 64bit Fedora. I
|
46
|
+
occasionally test it on a 32bit CentOS machine, and recently tested it
|
47
|
+
on a 32bit MacBook. It built and passed tests with no issues. My
|
48
|
+
knowledge of building either Ruby or LLVM on Windows is minimal. It
|
49
|
+
should be doable, but I don't believe LLVM currently is usable with
|
50
|
+
VC++, which is the main compiler for Ruby on Windows, so you may run
|
51
|
+
into fun times trying to figure out a good way to make that go.
|
52
|
+
|
53
|
+
* Things that definitely do not work right now
|
54
|
+
|
55
|
+
No attempt has been made to properly free LLVM objects. This probably
|
56
|
+
isn't hard, LLVM api has easy to deal with memory management. Many LLVM
|
57
|
+
objects end up owned by modules/execution engine and shouldn't be freed
|
58
|
+
normally anyway.
|
59
|
+
|
60
|
+
There needs to be a lot more exception raising when arguments are of wrong
|
61
|
+
number/type.
|
62
|
+
|
63
|
+
Malformed LLVM functions will cause the program to abort, even just
|
64
|
+
from calling verify on a module. This seems like a bug in LLVM.
|
65
|
+
Verification in theory is slow and should be used only for debugging, but
|
66
|
+
it would nice if tests did not abort and die because of missing block
|
67
|
+
terminators or whatever.
|
68
|
+
|
69
|
+
* Copying
|
70
|
+
|
71
|
+
See the file COPYING
|
72
|
+
|
73
|
+
* Author
|
74
|
+
|
75
|
+
For questions or answers, my email is: tomatobagby@gmail.com
|
76
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
desc "Run the tests"
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << 'ext'
|
6
|
+
t.test_files = FileList['test/test*.rb']
|
7
|
+
t.warning = true
|
8
|
+
end
|
9
|
+
|
10
|
+
OBJ = "ext/llvmruby." + Config::CONFIG["DLEXT"]
|
11
|
+
|
12
|
+
file "ext/Makefile" do
|
13
|
+
#cmd = "extconf.rb --with-llvm-include=`llvm-config --includedir` --with-llvm-lib=`llvm-config --libdir`"
|
14
|
+
cmd = 'extconf.rb'
|
15
|
+
Dir.chdir("ext") { ruby(cmd) }
|
16
|
+
end
|
17
|
+
|
18
|
+
file OBJ => %w(ext/Makefile) + FileList["ext/*.{cpp,c,h}"] do
|
19
|
+
Dir.chdir("ext") { sh "make" }
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Compile llvmruby extensions"
|
23
|
+
task :compile => OBJ
|
24
|
+
task :default => :compile
|
25
|
+
|
26
|
+
desc "Remove compiled files"
|
27
|
+
task :clean do |t|
|
28
|
+
for file in FileList.new("ext/*.o", "ext/Makefile", "ext/mkmf.log", OBJ)
|
29
|
+
File.delete(file) rescue true
|
30
|
+
end
|
31
|
+
end
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
extension_name = 'llvmruby'
|
4
|
+
|
5
|
+
dir_config(extension_name)
|
6
|
+
dir_config('llvm', `llvm-config --includedir`.strip, `llvm-config --libdir`.strip)
|
7
|
+
|
8
|
+
have_library('stdc++')
|
9
|
+
have_library('pthread')
|
10
|
+
|
11
|
+
with_ldflags(`llvm-config --libs all`) do
|
12
|
+
create_makefile(extension_name)
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,299 @@
|
|
1
|
+
#include "llvmruby.h"
|
2
|
+
|
3
|
+
extern VALUE cLLVMBasicBlock;
|
4
|
+
extern VALUE cLLVMBuilder;
|
5
|
+
|
6
|
+
extern "C" {
|
7
|
+
VALUE
|
8
|
+
llvm_basic_block_wrap(BasicBlock* bb) {
|
9
|
+
return Data_Wrap_Struct(cLLVMBasicBlock, NULL, NULL, bb);
|
10
|
+
}
|
11
|
+
|
12
|
+
VALUE
|
13
|
+
llvm_basic_block_size(VALUE self) {
|
14
|
+
BasicBlock *bb = LLVM_BASIC_BLOCK(self);
|
15
|
+
return INT2NUM(bb->size());
|
16
|
+
}
|
17
|
+
|
18
|
+
VALUE
|
19
|
+
llvm_basic_block_get_instruction_list(VALUE self) {
|
20
|
+
BasicBlock *bb = LLVM_BASIC_BLOCK(self);
|
21
|
+
VALUE ins_array = rb_ary_new();
|
22
|
+
BasicBlock::iterator ins = bb->begin();
|
23
|
+
while(ins != bb->end()) {
|
24
|
+
Instruction *i = ins++;
|
25
|
+
rb_ary_push(ins_array, llvm_instruction_wrap(i));
|
26
|
+
}
|
27
|
+
return ins_array;
|
28
|
+
}
|
29
|
+
|
30
|
+
VALUE
|
31
|
+
llvm_basic_block_builder(VALUE self) {
|
32
|
+
BasicBlock* bb;
|
33
|
+
Data_Get_Struct(self, BasicBlock, bb);
|
34
|
+
IRBuilder<> *builder = new IRBuilder<>(bb);
|
35
|
+
return Data_Wrap_Struct(cLLVMBuilder, NULL, NULL, builder);
|
36
|
+
}
|
37
|
+
|
38
|
+
#define DATA_GET_BUILDER IRBuilder<> *builder; Data_Get_Struct(self, IRBuilder<>, builder);
|
39
|
+
#define DATA_GET_BLOCK BasicBlock *bb; CHECK_TYPE(rbb, cLLVMBasicBlock); Data_Get_Struct(rbb, BasicBlock, bb);
|
40
|
+
|
41
|
+
VALUE
|
42
|
+
llvm_builder_set_insert_point(VALUE self, VALUE rbb) {
|
43
|
+
DATA_GET_BUILDER
|
44
|
+
DATA_GET_BLOCK
|
45
|
+
builder->SetInsertPoint(bb);
|
46
|
+
return self;
|
47
|
+
}
|
48
|
+
|
49
|
+
VALUE
|
50
|
+
llvm_builder_bin_op(VALUE self, VALUE rbin_op, VALUE rv1, VALUE rv2) {
|
51
|
+
Check_Type(rbin_op, T_FIXNUM);
|
52
|
+
DATA_GET_BUILDER
|
53
|
+
|
54
|
+
Instruction::BinaryOps bin_op = (Instruction::BinaryOps)FIX2INT(rbin_op);
|
55
|
+
|
56
|
+
Value *v1, *v2;
|
57
|
+
Data_Get_Struct(rv1, Value, v1);
|
58
|
+
Data_Get_Struct(rv2, Value, v2);
|
59
|
+
Value *res = builder->CreateBinOp(bin_op, v1, v2);
|
60
|
+
return Data_Wrap_Struct(cLLVMBinaryOperator, NULL, NULL, res);
|
61
|
+
}
|
62
|
+
|
63
|
+
VALUE
|
64
|
+
llvm_builder_phi(VALUE self, VALUE type) {
|
65
|
+
CHECK_TYPE(type, cLLVMType);
|
66
|
+
DATA_GET_BUILDER
|
67
|
+
PHINode *v = builder->CreatePHI(LLVM_TYPE(type));
|
68
|
+
return Data_Wrap_Struct(cLLVMPhi, NULL, NULL, v);
|
69
|
+
}
|
70
|
+
|
71
|
+
VALUE
|
72
|
+
llvm_phi_add_incoming(VALUE self, VALUE val, VALUE rbb) {
|
73
|
+
CHECK_TYPE(val, cLLVMValue);
|
74
|
+
|
75
|
+
DATA_GET_BLOCK
|
76
|
+
PHINode *phi = LLVM_PHI(self);
|
77
|
+
|
78
|
+
phi->addIncoming(LLVM_VAL(val), bb);
|
79
|
+
return self;
|
80
|
+
}
|
81
|
+
|
82
|
+
VALUE
|
83
|
+
llvm_builder_return(VALUE self, VALUE rv) {
|
84
|
+
CHECK_TYPE(rv, cLLVMValue);
|
85
|
+
DATA_GET_BUILDER
|
86
|
+
return Data_Wrap_Struct(cLLVMReturnInst, NULL, NULL, builder->CreateRet(LLVM_VAL(rv)));
|
87
|
+
}
|
88
|
+
|
89
|
+
VALUE
|
90
|
+
llvm_builder_br(VALUE self, VALUE rblock) {
|
91
|
+
DATA_GET_BUILDER
|
92
|
+
|
93
|
+
BasicBlock *bb;
|
94
|
+
Data_Get_Struct(rblock, BasicBlock, bb);
|
95
|
+
|
96
|
+
Value *branch_instr = builder->CreateBr(bb);
|
97
|
+
return Data_Wrap_Struct(cLLVMBranchInst, NULL, NULL, branch_instr);
|
98
|
+
}
|
99
|
+
|
100
|
+
VALUE
|
101
|
+
llvm_builder_cond_br(VALUE self, VALUE rcond, VALUE rtrue_block, VALUE rfalse_block) {
|
102
|
+
DATA_GET_BUILDER
|
103
|
+
|
104
|
+
Value *cond;
|
105
|
+
Data_Get_Struct(rcond, Value, cond);
|
106
|
+
|
107
|
+
BasicBlock *true_block, *false_block;
|
108
|
+
Data_Get_Struct(rtrue_block, BasicBlock, true_block);
|
109
|
+
Data_Get_Struct(rfalse_block, BasicBlock, false_block);
|
110
|
+
|
111
|
+
Value *branch_instr = builder->CreateCondBr(cond, true_block, false_block);
|
112
|
+
return Data_Wrap_Struct(cLLVMBranchInst, NULL, NULL, branch_instr);
|
113
|
+
}
|
114
|
+
|
115
|
+
VALUE
|
116
|
+
llvm_builder_switch(VALUE self, VALUE rv, VALUE rdefault) {
|
117
|
+
DATA_GET_BUILDER
|
118
|
+
|
119
|
+
BasicBlock *deflt;
|
120
|
+
Data_Get_Struct(rdefault, BasicBlock, deflt);
|
121
|
+
|
122
|
+
Value *v;
|
123
|
+
Data_Get_Struct(rv, Value, v);
|
124
|
+
|
125
|
+
Instruction *switch_instr = builder->CreateSwitch(v, deflt);
|
126
|
+
return llvm_instruction_wrap(switch_instr);
|
127
|
+
}
|
128
|
+
|
129
|
+
VALUE
|
130
|
+
llvm_builder_malloc(VALUE self, VALUE rtype, VALUE rsize) {
|
131
|
+
DATA_GET_BUILDER
|
132
|
+
|
133
|
+
const Type *type;
|
134
|
+
Data_Get_Struct(rtype, Type, type);
|
135
|
+
|
136
|
+
Value *size = ConstantInt::get(Type::Int32Ty, FIX2INT(rsize));
|
137
|
+
Instruction *v = builder->CreateMalloc(type, size);
|
138
|
+
return llvm_instruction_wrap(v);
|
139
|
+
}
|
140
|
+
|
141
|
+
VALUE
|
142
|
+
llvm_builder_free(VALUE self, VALUE rptr) {
|
143
|
+
DATA_GET_BUILDER
|
144
|
+
Value *v = LLVM_VAL(rptr);
|
145
|
+
Instruction *free_inst = builder->CreateFree(v);
|
146
|
+
return llvm_instruction_wrap(free_inst);
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE
|
150
|
+
llvm_builder_alloca(VALUE self, VALUE rtype, VALUE rsize) {
|
151
|
+
DATA_GET_BUILDER
|
152
|
+
|
153
|
+
const Type* type;
|
154
|
+
Data_Get_Struct(rtype, Type, type);
|
155
|
+
|
156
|
+
Value *size = ConstantInt::get(Type::Int32Ty, FIX2INT(rsize));
|
157
|
+
Instruction *v = builder->CreateAlloca(type, size);
|
158
|
+
return Data_Wrap_Struct(cLLVMAllocationInst, NULL, NULL, v);
|
159
|
+
}
|
160
|
+
|
161
|
+
VALUE
|
162
|
+
llvm_builder_load(VALUE self, VALUE rptr) {
|
163
|
+
DATA_GET_BUILDER
|
164
|
+
|
165
|
+
Value *ptr;
|
166
|
+
Data_Get_Struct(rptr, Value, ptr);
|
167
|
+
return Data_Wrap_Struct(cLLVMLoadInst, NULL, NULL, builder->CreateLoad(ptr));
|
168
|
+
}
|
169
|
+
|
170
|
+
VALUE
|
171
|
+
llvm_builder_store(VALUE self, VALUE rv, VALUE rptr) {
|
172
|
+
DATA_GET_BUILDER
|
173
|
+
|
174
|
+
Value *v, *ptr;
|
175
|
+
Data_Get_Struct(rv, Value, v);
|
176
|
+
Data_Get_Struct(rptr, Value, ptr);
|
177
|
+
return Data_Wrap_Struct(cLLVMStoreInst, NULL, NULL, builder->CreateStore(v, ptr));
|
178
|
+
}
|
179
|
+
|
180
|
+
VALUE
|
181
|
+
llvm_builder_icmp(VALUE self, VALUE pred, VALUE lhs, VALUE rhs) {
|
182
|
+
DATA_GET_BUILDER
|
183
|
+
|
184
|
+
CmpInst::Predicate p = (CmpInst::Predicate)FIX2INT(pred);
|
185
|
+
Value *v = builder->CreateICmp(p, LLVM_VAL(lhs), LLVM_VAL(rhs));
|
186
|
+
return Data_Wrap_Struct(cLLVMICmpInst, NULL, NULL, v);
|
187
|
+
}
|
188
|
+
|
189
|
+
VALUE
|
190
|
+
llvm_builder_fcmp(VALUE self, VALUE pred, VALUE lhs, VALUE rhs) {
|
191
|
+
DATA_GET_BUILDER
|
192
|
+
|
193
|
+
CmpInst::Predicate p = (CmpInst::Predicate)FIX2INT(pred);
|
194
|
+
Value *v = builder->CreateFCmp(p, LLVM_VAL(lhs), LLVM_VAL(rhs));
|
195
|
+
return Data_Wrap_Struct(cLLVMFCmpInst, NULL, NULL, v);
|
196
|
+
}
|
197
|
+
|
198
|
+
VALUE
|
199
|
+
llvm_builder_gep(VALUE self, VALUE rptr, VALUE ridx) {
|
200
|
+
DATA_GET_BUILDER
|
201
|
+
|
202
|
+
Value *ptr, *idx;
|
203
|
+
Data_Get_Struct(rptr, Value, ptr);
|
204
|
+
Data_Get_Struct(ridx, Value, idx);
|
205
|
+
return llvm_value_wrap(builder->CreateGEP(ptr, idx));
|
206
|
+
}
|
207
|
+
|
208
|
+
VALUE
|
209
|
+
llvm_builder_struct_gep(VALUE self, VALUE rptr, VALUE ridx) {
|
210
|
+
DATA_GET_BUILDER
|
211
|
+
|
212
|
+
Value *ptr;
|
213
|
+
Data_Get_Struct(rptr, Value, ptr);
|
214
|
+
return llvm_value_wrap(builder->CreateStructGEP(ptr, FIX2INT(ridx)));
|
215
|
+
}
|
216
|
+
|
217
|
+
VALUE
|
218
|
+
llvm_builder_cast(VALUE self, VALUE rop, VALUE rv, VALUE rdest_ty) {
|
219
|
+
DATA_GET_BUILDER
|
220
|
+
|
221
|
+
Instruction::CastOps op = (Instruction::CastOps)FIX2INT(rop);
|
222
|
+
|
223
|
+
Value *v;
|
224
|
+
Data_Get_Struct(rv, Value, v);
|
225
|
+
|
226
|
+
Type *dest_ty;
|
227
|
+
Data_Get_Struct(rdest_ty, Type, dest_ty);
|
228
|
+
|
229
|
+
return llvm_value_wrap(builder->CreateCast(op, v, dest_ty));
|
230
|
+
}
|
231
|
+
|
232
|
+
VALUE
|
233
|
+
llvm_builder_int_to_ptr(VALUE self, VALUE ri, VALUE rtype) {
|
234
|
+
DATA_GET_BUILDER
|
235
|
+
|
236
|
+
Value *i;
|
237
|
+
Data_Get_Struct(ri, Value, i);
|
238
|
+
|
239
|
+
const Type* type;
|
240
|
+
Data_Get_Struct(rtype, Type, type);
|
241
|
+
|
242
|
+
return llvm_value_wrap(builder->CreateIntToPtr(i, type));
|
243
|
+
}
|
244
|
+
|
245
|
+
VALUE llvm_builder_int_cast(VALUE self, VALUE i, VALUE type, VALUE sign) {
|
246
|
+
DATA_GET_BUILDER
|
247
|
+
bool isSigned = (sign != Qnil && sign != Qfalse);
|
248
|
+
return llvm_value_wrap(builder->CreateIntCast(LLVM_VAL(i), LLVM_TYPE(type), isSigned));
|
249
|
+
}
|
250
|
+
|
251
|
+
VALUE
|
252
|
+
llvm_builder_call(int argc, VALUE* argv, VALUE self) {
|
253
|
+
DATA_GET_BUILDER
|
254
|
+
|
255
|
+
Function *callee = LLVM_FUNCTION(argv[0]);
|
256
|
+
int num_args = argc-1;
|
257
|
+
Value** args = (Value**)alloca(num_args*sizeof(Value*));
|
258
|
+
for(int i = 0; i < num_args; ++i) {
|
259
|
+
args[i] = LLVM_VAL(argv[i+1]);
|
260
|
+
}
|
261
|
+
return llvm_value_wrap(builder->CreateCall(callee, args, args+num_args));
|
262
|
+
}
|
263
|
+
|
264
|
+
VALUE
|
265
|
+
llvm_builder_insert_element(VALUE self, VALUE rv, VALUE rnv, VALUE ridx) {
|
266
|
+
DATA_GET_BUILDER
|
267
|
+
|
268
|
+
Value *v, *nv, *idx;
|
269
|
+
Data_Get_Struct(rv, Value, v);
|
270
|
+
Data_Get_Struct(rnv, Value, nv);
|
271
|
+
Data_Get_Struct(ridx, Value, idx);
|
272
|
+
|
273
|
+
return llvm_value_wrap(builder->CreateInsertElement(v, nv, idx));
|
274
|
+
}
|
275
|
+
|
276
|
+
VALUE
|
277
|
+
llvm_builder_extract_element(VALUE self, VALUE rv, VALUE ridx) {
|
278
|
+
DATA_GET_BUILDER
|
279
|
+
|
280
|
+
Value *v, *idx;
|
281
|
+
Data_Get_Struct(rv, Value, v);
|
282
|
+
Data_Get_Struct(ridx, Value, idx);
|
283
|
+
|
284
|
+
return llvm_value_wrap(builder->CreateExtractElement(v, idx));
|
285
|
+
}
|
286
|
+
|
287
|
+
VALUE
|
288
|
+
llvm_builder_get_global(VALUE self) {
|
289
|
+
GlobalVariable *g = new GlobalVariable(Type::Int64Ty, false, GlobalValue::ExternalLinkage, 0, "shakalaka");
|
290
|
+
return llvm_value_wrap(g);
|
291
|
+
}
|
292
|
+
|
293
|
+
VALUE
|
294
|
+
llvm_builder_create_global_string_ptr(VALUE self, VALUE str) {
|
295
|
+
DATA_GET_BUILDER
|
296
|
+
Value *v = builder->CreateGlobalStringPtr(StringValuePtr(str));
|
297
|
+
return llvm_value_wrap(v);
|
298
|
+
}
|
299
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#include "llvmruby.h"
|
2
|
+
#include <sstream>
|
3
|
+
|
4
|
+
extern "C" {
|
5
|
+
VALUE
|
6
|
+
llvm_function_wrap(Function *f) {
|
7
|
+
return Data_Wrap_Struct(cLLVMFunction, NULL, NULL, f);
|
8
|
+
}
|
9
|
+
|
10
|
+
VALUE
|
11
|
+
llvm_function_create_block(VALUE self) {
|
12
|
+
BasicBlock *bb = BasicBlock::Create("bb", LLVM_FUNCTION(self));
|
13
|
+
return llvm_basic_block_wrap(bb);
|
14
|
+
}
|
15
|
+
|
16
|
+
VALUE
|
17
|
+
llvm_function_arguments(VALUE self) {
|
18
|
+
Function *f = LLVM_FUNCTION(self);
|
19
|
+
VALUE arg_array = rb_ary_new();
|
20
|
+
Function::arg_iterator args = f->arg_begin();
|
21
|
+
while(args != f->arg_end()) {
|
22
|
+
Value *arg = args++;
|
23
|
+
rb_ary_push(arg_array, llvm_value_wrap(arg));
|
24
|
+
}
|
25
|
+
return arg_array;
|
26
|
+
}
|
27
|
+
|
28
|
+
VALUE
|
29
|
+
llvm_function_inspect(VALUE self) {
|
30
|
+
Function *f = LLVM_FUNCTION(self);
|
31
|
+
std::ostringstream strstrm;
|
32
|
+
strstrm << *f;
|
33
|
+
return rb_str_new2(strstrm.str().c_str());
|
34
|
+
}
|
35
|
+
|
36
|
+
VALUE
|
37
|
+
llvm_function_get_basic_block_list(VALUE self) {
|
38
|
+
Function *f = LLVM_FUNCTION(self);
|
39
|
+
VALUE bb_array = rb_ary_new();
|
40
|
+
Function::iterator bbs = f->begin();
|
41
|
+
while(bbs != f->end()) {
|
42
|
+
BasicBlock *bb = bbs++;
|
43
|
+
rb_ary_push(bb_array, llvm_basic_block_wrap(bb));
|
44
|
+
}
|
45
|
+
return bb_array;
|
46
|
+
}
|
47
|
+
|
48
|
+
}
|