<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -107,6 +107,11 @@ llvm_builder_cond_br(VALUE self, VALUE rcond, VALUE rtrue_block, VALUE rfalse_bl
   BasicBlock *true_block, *false_block;
   Data_Get_Struct(rtrue_block, BasicBlock, true_block);
   Data_Get_Struct(rfalse_block, BasicBlock, false_block);
+#if defined(USE_ASSERT_CHECK)
+  if (cond-&gt;getType() != Type::Int1Ty) {
+    rb_raise(rb_eRuntimeError, &quot;May only branch on boolean predicates!&quot;);
+  }
+#endif
 
   Value *branch_instr = builder-&gt;CreateCondBr(cond, true_block, false_block);
   return Data_Wrap_Struct(cLLVMBranchInst, NULL, NULL, branch_instr);
@@ -127,6 +132,32 @@ llvm_builder_switch(VALUE self, VALUE rv, VALUE rdefault) {
 }
 
 VALUE
+llvm_builder_invoke(int argc, VALUE *argv, VALUE self) {
+  DATA_GET_BUILDER
+  if(argc &lt; 3) { rb_raise(rb_eArgError, &quot;Expected at least three argument&quot;); }
+  int num_args = argc - 3;
+
+  Value *callee = LLVM_VAL(argv[0]);
+  BasicBlock *ndest;
+  BasicBlock *udest;
+  std::vector&lt;Value *&gt; vecarg(num_args);
+
+  Data_Get_Struct(argv[1], BasicBlock, ndest);
+  Data_Get_Struct(argv[2], BasicBlock, udest);
+  for (int i = 0; i &lt; num_args; i++) {
+    vecarg[i] = LLVM_VAL(argv[i + 3]);
+  }
+  
+  return llvm_value_wrap(builder-&gt;CreateInvoke(callee, ndest, udest, vecarg.begin(), vecarg.end()));
+}
+
+VALUE
+llvm_builder_unwind(VALUE self) {
+  DATA_GET_BUILDER
+  return llvm_value_wrap(builder-&gt;CreateUnwind());
+}
+
+VALUE
 llvm_builder_malloc(VALUE self, VALUE rtype, VALUE rsize) {
   DATA_GET_BUILDER
 
@@ -159,22 +190,30 @@ llvm_builder_alloca(VALUE self, VALUE rtype, VALUE rsize) {
 }
 
 VALUE
-llvm_builder_load(VALUE self, VALUE rptr) {
+llvm_builder_load(int argc, VALUE *argv, VALUE self) {
   DATA_GET_BUILDER
-
+  VALUE rptr;
+  VALUE isVolatile;
   Value *ptr;
+
+  rb_scan_args(argc, argv, &quot;11&quot;, &amp;rptr, &amp;isVolatile);
   Data_Get_Struct(rptr, Value, ptr);
-  return Data_Wrap_Struct(cLLVMLoadInst, NULL, NULL, builder-&gt;CreateLoad(ptr));
+  return Data_Wrap_Struct(cLLVMLoadInst, NULL, NULL, builder-&gt;CreateLoad(ptr, RTEST(isVolatile)));
 }
 
 VALUE
-llvm_builder_store(VALUE self, VALUE rv, VALUE rptr) {
+llvm_builder_store(int argc, VALUE *argv, VALUE self) {
   DATA_GET_BUILDER
 
   Value *v, *ptr;
+  VALUE rv;
+  VALUE rptr;
+  VALUE isVolatile;
+
+  rb_scan_args(argc, argv, &quot;21&quot;, &amp;rv, &amp;rptr, &amp;isVolatile);
   Data_Get_Struct(rv, Value, v);
   Data_Get_Struct(rptr, Value, ptr);
-  return Data_Wrap_Struct(cLLVMStoreInst, NULL, NULL, builder-&gt;CreateStore(v, ptr));
+  return Data_Wrap_Struct(cLLVMStoreInst, NULL, NULL, builder-&gt;CreateStore(v, ptr, RTEST(isVolatile)));
 }
 
 VALUE
@@ -255,8 +294,31 @@ llvm_builder_call(int argc, VALUE* argv, VALUE self) {
   Function *callee = LLVM_FUNCTION(argv[0]);
   int num_args = argc-1;
   Value** args = (Value**)alloca(num_args*sizeof(Value*));
+
+#if defined(USE_ASSERT_CHECK)
+  const FunctionType *FTy =
+    cast&lt;FunctionType&gt;(cast&lt;PointerType&gt;(callee-&gt;getType())-&gt;getElementType());
+  char message[255];
+  if (!((unsigned)num_args == FTy-&gt;getNumParams() ||
+	(FTy-&gt;isVarArg() &amp;&amp; (unsigned) num_args &gt; FTy-&gt;getNumParams()))) {
+    snprintf(message, 255, 
+	     &quot;Calling a function with bad signature number of argument %d expect %d&quot;, 
+	     num_args, FTy-&gt;getNumParams());
+    rb_raise(rb_eRuntimeError, message);
+  }
+#endif
+
   for(int i = 0; i &lt; num_args; ++i) {
     args[i] = LLVM_VAL(argv[i+1]); 
+
+#if defined(USE_ASSERT_CHECK)
+    if (FTy-&gt;getParamType(i) != args[i]-&gt;getType()) {
+      snprintf(message, 255, 
+	       &quot;Calling a function with a bad signature in %d argument&quot;, 
+	       i);
+      rb_raise(rb_eRuntimeError, message);
+    }
+#endif
   }
   return llvm_value_wrap(builder-&gt;CreateCall(callee, args, args+num_args));
 }</diff>
      <filename>ext/llvm_basicblock.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,7 @@
 #include &quot;llvm/Bitcode/ReaderWriter.h&quot;
 #include &quot;llvm/Analysis/Verifier.h&quot;
 #include &quot;llvm/Support/MemoryBuffer.h&quot;
+#include &quot;llvm/System/DynamicLibrary.h&quot;
 #include &lt;fstream&gt;
 #include &lt;sstream&gt;
 
@@ -27,7 +28,16 @@ llvm_module_get_or_insert_function(VALUE self, VALUE name, VALUE rtype) {
 
   Module *m = LLVM_MODULE(self);
   FunctionType *type = LLVM_FUNC_TYPE(rtype);
-  Function *f = cast&lt;Function&gt;(m-&gt;getOrInsertFunction(StringValuePtr(name), type));
+  Constant *fn = m-&gt;getOrInsertFunction(StringValuePtr(name), type);
+
+#if defined(USE_ASSERT_CHECK)
+  if (isa&lt;Function&gt;(fn) == 0) {
+    rb_raise(rb_eRuntimeError, 
+	     &quot;cast&lt;Function&gt;(fn) argument of incompatible type !&quot;);
+  }
+#endif
+
+  Function *f = cast&lt;Function&gt;(fn);
   return llvm_function_wrap(f); 
 }
 
@@ -40,7 +50,7 @@ llvm_module_get_function(VALUE self, VALUE name) {
 }
 
 VALUE
-llvm_module_global_variable(VALUE self, VALUE rtype, VALUE rinitializer) {
+llvm_module_global_constant(VALUE self, VALUE rtype, VALUE rinitializer) {
   Module *m = LLVM_MODULE(self);
   Type *type = LLVM_TYPE(rtype);
   Constant *initializer = (Constant*)DATA_PTR(rinitializer);
@@ -48,6 +58,15 @@ llvm_module_global_variable(VALUE self, VALUE rtype, VALUE rinitializer) {
   return llvm_value_wrap(gv);
 }
 
+VALUE
+llvm_module_global_variable(VALUE self, VALUE rtype, VALUE rinitializer) {
+  Module *m = LLVM_MODULE(self);
+  Type *type = LLVM_TYPE(rtype);
+  Constant *initializer = (Constant*)DATA_PTR(rinitializer);
+  GlobalVariable *gv = new GlobalVariable(type, false, GlobalValue::InternalLinkage, initializer, &quot;&quot;, m);
+  return llvm_value_wrap(gv);
+}
+
 
 VALUE
 llvm_module_inspect(VALUE self) {
@@ -94,6 +113,14 @@ VALUE
 llvm_execution_engine_get(VALUE klass, VALUE module) {
   CHECK_TYPE(module, cLLVMModule);
 
+#if defined(__CYGWIN__)
+
+  // Load dll Modules for ruby
+  sys::DynamicLibrary::LoadLibraryPermanently(&quot;cygwin1.dll&quot;);
+  sys::DynamicLibrary::LoadLibraryPermanently(&quot;cygruby190.dll&quot;);
+
+#endif
+
   Module *m = LLVM_MODULE(module);
   ExistingModuleProvider *MP = new ExistingModuleProvider(m);
 
@@ -139,7 +166,12 @@ VALUE
 llvm_module_read_bitcode(VALUE self, VALUE bitcode) {
   Check_Type(bitcode, T_STRING);
 
+#if defined(RSTRING_PTR)
+  MemoryBuffer *buf = MemoryBuffer::getMemBufferCopy(RSTRING_PTR(bitcode),RSTRING_PTR(bitcode)+RSTRING_LEN(bitcode));  
+#else
   MemoryBuffer *buf = MemoryBuffer::getMemBufferCopy(RSTRING(bitcode)-&gt;ptr,RSTRING(bitcode)-&gt;ptr+RSTRING(bitcode)-&gt;len);
+#endif
+
   Module *module = ParseBitcodeFile(buf);
   delete buf;
   return Data_Wrap_Struct(cLLVMModule, NULL, NULL, module);</diff>
      <filename>ext/llvm_module.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -70,12 +70,20 @@ llvm_value_get_constant(VALUE self, VALUE type, VALUE v) {
 
 VALUE 
 llvm_value_get_float_constant(VALUE self, VALUE v) {
+#if defined(RFLOAT_VALUE)
+  return llvm_value_wrap(ConstantFP::get(Type::FloatTy, RFLOAT_VALUE(v)));
+#else
   return llvm_value_wrap(ConstantFP::get(Type::FloatTy, RFLOAT(v)-&gt;value));
+#endif
 }
 
 VALUE 
 llvm_value_get_double_constant(VALUE self, VALUE v) {
+#if defined(RFLOAT_VALUE)
+  return llvm_value_wrap(ConstantFP::get(Type::DoubleTy, RFLOAT_VALUE(v)));
+#else
   return llvm_value_wrap(ConstantFP::get(Type::DoubleTy, RFLOAT(v)-&gt;value));
+#endif
 }
 
 VALUE</diff>
      <filename>ext/llvm_value.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -48,6 +48,7 @@ VALUE llvm_module_allocate(VALUE);
 VALUE llvm_module_initialize(VALUE); 
 VALUE llvm_module_get_or_insert_function(VALUE, VALUE);
 VALUE llvm_module_get_function(VALUE, VALUE);
+VALUE llvm_module_global_constant(VALUE, VALUE, VALUE);
 VALUE llvm_module_global_variable(VALUE, VALUE, VALUE);
 VALUE llvm_module_external_function(VALUE, VALUE, VALUE);
 VALUE llvm_module_read_assembly(VALUE, VALUE);
@@ -98,12 +99,14 @@ VALUE llvm_builder_return(VALUE, VALUE);
 VALUE llvm_builder_br(VALUE, VALUE);
 VALUE llvm_builder_cond_br(VALUE, VALUE, VALUE, VALUE);
 VALUE llvm_builder_switch(VALUE, VALUE, VALUE);
+VALUE llvm_builder_invoke(int, VALUE *, VALUE);
+VALUE llvm_builder_unwind(VALUE, VALUE, VALUE);
 
 VALUE llvm_builder_malloc(VALUE, VALUE, VALUE);
 VALUE llvm_builder_free(VALUE, VALUE);
 VALUE llvm_builder_alloca(VALUE, VALUE, VALUE);
-VALUE llvm_builder_load(VALUE, VALUE);
-VALUE llvm_builder_store(VALUE, VALUE, VALUE);
+VALUE llvm_builder_load(int, VALUE *,  VALUE);
+VALUE llvm_builder_store(int, VALUE *, VALUE);
 VALUE llvm_builder_icmp(VALUE, VALUE, VALUE, VALUE);
 VALUE llvm_builder_fcmp(VALUE, VALUE, VALUE, VALUE);
 VALUE llvm_builder_gep(VALUE, VALUE, VALUE);
@@ -241,6 +244,7 @@ void Init_llvmruby() {
   rb_define_method(cLLVMModule, &quot;initialize&quot;, llvm_module_initialize, 1);
   rb_define_method(cLLVMModule, &quot;get_or_insert_function&quot;, llvm_module_get_or_insert_function, 2);
   rb_define_method(cLLVMModule, &quot;get_function&quot;, llvm_module_get_function, 1);
+  rb_define_method(cLLVMModule, &quot;global_constant&quot;, llvm_module_global_constant, 2);
   rb_define_method(cLLVMModule, &quot;global_variable&quot;, llvm_module_global_variable, 2);
   rb_define_method(cLLVMModule, &quot;external_function&quot;, llvm_module_external_function, 2);
   rb_define_method(cLLVMModule, &quot;write_bitcode&quot;, llvm_module_write_bitcode, 1);
@@ -288,11 +292,13 @@ void Init_llvmruby() {
   rb_define_method(cLLVMBuilder, &quot;br&quot;, llvm_builder_br, 1);
   rb_define_method(cLLVMBuilder, &quot;cond_br&quot;, llvm_builder_cond_br, 3);
   rb_define_method(cLLVMBuilder, &quot;switch&quot;, llvm_builder_switch, 2);
+  rb_define_method(cLLVMBuilder, &quot;invoke&quot;, llvm_builder_invoke, -1);
+  rb_define_method(cLLVMBuilder, &quot;unwind&quot;, llvm_builder_unwind, 0);
   rb_define_method(cLLVMBuilder, &quot;malloc&quot;, llvm_builder_malloc, 2);
   rb_define_method(cLLVMBuilder, &quot;free&quot;, llvm_builder_free, 1);
   rb_define_method(cLLVMBuilder, &quot;alloca&quot;, llvm_builder_alloca, 2);
-  rb_define_method(cLLVMBuilder, &quot;load&quot;, llvm_builder_load, 1);
-  rb_define_method(cLLVMBuilder, &quot;store&quot;, llvm_builder_store, 2);
+  rb_define_method(cLLVMBuilder, &quot;load&quot;, llvm_builder_load, -1);
+  rb_define_method(cLLVMBuilder, &quot;store&quot;, llvm_builder_store, -1);
   rb_define_method(cLLVMBuilder, &quot;icmp&quot;, llvm_builder_icmp, 3);
   rb_define_method(cLLVMBuilder, &quot;fcmp&quot;, llvm_builder_fcmp, 3);
 </diff>
      <filename>ext/llvmruby.c</filename>
    </modified>
    <modified>
      <diff>@@ -63,6 +63,9 @@ extern VALUE cLLVMPassManager;
     rb_raise(rb_eTypeError, &quot;wrong argument type: %s given, expected %s&quot;, rb_obj_classname(val), rb_class2name(klass));\
   }
 
+
+#define USE_ASSERT_CHECK
+
 extern &quot;C&quot; {
 VALUE llvm_value_wrap(Value*);
 VALUE llvm_user_wrap(User*);</diff>
      <filename>ext/llvmruby.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 spec = Gem::Specification.new do |s|
     s.platform      = Gem::Platform::RUBY
     s.name          = &quot;llvmruby&quot;
-    s.version       = &quot;0.0.5&quot; # Can't require version file on Github
+    s.version       = &quot;0.0.6&quot; # Can't require version file on Github
     s.summary       = &quot;Ruby bindings to LLVM&quot;
     s.authors       = [ &quot;Thomas Bagby&quot;, &quot;Christian Plessl&quot; ]
     s.email         = [ &quot;tomatobagby@gmail.com&quot;, &quot;christian@plesslweb.ch&quot; ]</diff>
      <filename>llvmruby.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -265,6 +265,17 @@ class BasicTests &lt; Test::Unit::TestCase
     assert_kind_of(Value, struct_const)
 
     m = LLVM::Module.new('globals')
+    gv = m.global_constant(struct_type, struct_const)
+    assert_kind_of(Value, gv)
+  end
+
+  def test_struct_variable
+    int_t = Type::Int32Ty
+    struct_type = Type.struct([int_t, int_t, int_t])
+    struct_const = Value.get_struct_constant(struct_type, 2.llvm(int_t), 3.llvm(int_t), 5.llvm(int_t))
+    assert_kind_of(Value, struct_const)
+
+    m = LLVM::Module.new('globals')
     gv = m.global_variable(struct_type, struct_const)
     assert_kind_of(Value, gv)
   end
@@ -337,4 +348,25 @@ class BasicTests &lt; Test::Unit::TestCase
   def test_type_type_id
     assert_equal IntegerTyID, 2.llvm.type.type_id
   end
+
+  def test_invoke_unwind
+    m = LLVM::Module.new(&quot;unwind_test_module&quot;)
+    type = Type::function(MACHINE_WORD, [])
+    f2 = m.get_or_insert_function(&quot;unwind_test2&quot;, type)
+    b = f2.create_block.builder
+    b.unwind
+
+    type = Type::function(MACHINE_WORD, [])
+    f = m.get_or_insert_function(&quot;unwind_test&quot;, type)
+    b = f.create_block.builder
+    nd = f.create_block
+    ud = f.create_block
+    b.invoke(f2, nd, ud)
+    b.set_insert_point(ud)
+    b.return(3.llvm)
+    b.set_insert_point(nd)
+    b.return(1.llvm)
+    ExecutionEngine.get(m)
+    m.write_bitcode(&quot;test/foo.bc&quot;)
+  end
 end</diff>
      <filename>test/test_basic.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>e829dc87abd204a47f02d9ea3a45213fed17764a</id>
    </parent>
  </parents>
  <author>
    <name>Tom Bagby</name>
    <email>tbagby@kosmix.com</email>
  </author>
  <url>http://github.com/tombagby/llvmruby/commit/144bb46bded94648aaaf19c4bf686e1417579342</url>
  <id>144bb46bded94648aaaf19c4bf686e1417579342</id>
  <committed-date>2008-12-24T14:45:12-08:00</committed-date>
  <authored-date>2008-12-24T14:45:12-08:00</authored-date>
  <message>merge changes from miura, global variables and other good stuff, bumb the gem version</message>
  <tree>22f3df7f5b87e1de53d0a53e8005f4e2ecbfea9a</tree>
  <committer>
    <name>Tom Bagby</name>
    <email>tbagby@kosmix.com</email>
  </committer>
</commit>
