plessl-llvmruby 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|