[macruby-changes] [1469] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Wed Apr 22 16:04:33 PDT 2009


Revision: 1469
          http://trac.macosforge.org/projects/ruby/changeset/1469
Author:   lsansonetti at apple.com
Date:     2009-04-22 16:04:33 -0700 (Wed, 22 Apr 2009)
Log Message:
-----------
implemented incoming large structs (x86_64 only for now)

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/spec/macruby/method_spec.rb

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-04-22 22:58:20 UTC (rev 1468)
+++ MacRuby/branches/experimental/roxor.cpp	2009-04-22 23:04:33 UTC (rev 1469)
@@ -592,8 +592,9 @@
 	    return NULL;
 	}
 
-	size_t get_type_size(const Type *type) {
-	    return ee->getTargetData()->getTypeSizeInBits(type);
+	bool is_large_struct_type(const Type *type) {
+	    return type->getTypeID() == Type::StructTyID
+		&& ee->getTargetData()->getTypeSizeInBits(type) > 128;
 	}
 };
 
@@ -5218,6 +5219,11 @@
 				fslot);
 		    }
 
+		    if (GET_VM()->is_large_struct_type(bs_boxed->type)) {
+			// If this structure is too large, we need to pass its
+			// address and not its value, to conform to the ABI.
+			return slot;
+		    }
 		    return new LoadInst(slot, "", bb);
 		}
 	    }
@@ -5528,12 +5534,10 @@
 
     Value *sret = NULL;
 
-    if (ret_type->getTypeID() == Type::StructTyID
-	&& GET_VM()->get_type_size(ret_type) > 128) {
-
+    if (GET_VM()->is_large_struct_type(ret_type)) {
 	// We are returning a large struct, we need to pass a pointer as the
 	// first argument to the structure data and return void to conform to
-	// the ABI (at least x86_64).
+	// the ABI.
 	f_types.push_back(PointerType::getUnqual(ret_type));
 	sret = new AllocaInst(ret_type, "", bb);
 	params.push_back(sret);
@@ -5551,16 +5555,26 @@
     params.push_back(sel_arg);
 
     // Arguments.
+    std::vector<int> byval_args;
     for (int i = 0; i < argc; i++) {
 	p = GetFirstType(p, buf, sizeof buf);
-	//printf("arg[%d] type `%s'\n", i, buf);
+	const Type *llvm_type = convert_type(buf);
+	if (GET_VM()->is_large_struct_type(llvm_type)) {
+	    // We are passing a large struct, we need to mark this argument
+	    // with the byval attribute and configure the internal stub
+	    // call to pass a pointer to the structure, to conform to the
+	    // ABI.
+	    f_types.push_back(PointerType::getUnqual(llvm_type));
+	    byval_args.push_back(i + 3);
+	}
+	else {
+	    f_types.push_back(llvm_type);
+	}
 
-	f_types.push_back(convert_type(buf));
-
 	Value *index = ConstantInt::get(Type::Int32Ty, i);
 	Value *slot = GetElementPtrInst::Create(argv_arg, index, "", bb);
 	Value *arg_val = new LoadInst(slot, "", bb);
-	Value *new_val_slot = new AllocaInst(f_types[i + 2], "", bb);
+	Value *new_val_slot = new AllocaInst(llvm_type, "", bb);
 
 	params.push_back(compile_conversion_to_c(buf, arg_val, new_val_slot));
     }
@@ -5573,6 +5587,12 @@
     CallInst *imp_call = CallInst::Create(imp, params.begin(), params.end(),
 	    "", bb); 
 
+    for (std::vector<int>::iterator iter = byval_args.begin();
+	 iter != byval_args.end(); ++iter) {
+	
+	imp_call->addAttribute(*iter, Attribute::ByVal);
+    }
+
     // Compile retval.
     Value *retval;
     if (sret != NULL) {

Modified: MacRuby/branches/experimental/spec/macruby/method_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/method_spec.rb	2009-04-22 22:58:20 UTC (rev 1468)
+++ MacRuby/branches/experimental/spec/macruby/method_spec.rb	2009-04-22 23:04:33 UTC (rev 1469)
@@ -417,10 +417,8 @@
     o.methodAcceptingNSPoint(p).should == 1
     p = o.methodReturningNSSize
     o.methodAcceptingNSSize(p).should == 1
-=begin
     p = o.methodReturningNSRect
     o.methodAcceptingNSRect(p).should == 1
-=end
     p = o.methodReturningNSRange
     o.methodAcceptingNSRange(p).should == 1
 
@@ -432,12 +430,10 @@
     lambda { o.methodAcceptingNSSize(123) }.should raise_error(TypeError)
     lambda { o.methodAcceptingNSSize(Object.new) }.should raise_error(TypeError)
     lambda { o.methodAcceptingNSSize(o.methodReturningNSPoint) }.should raise_error(TypeError)
-=begin
     lambda { o.methodAcceptingNSRect(nil) }.should raise_error(TypeError)
     lambda { o.methodAcceptingNSRect(123) }.should raise_error(TypeError)
     lambda { o.methodAcceptingNSRect(Object.new) }.should raise_error(TypeError)
     lambda { o.methodAcceptingNSRect(o.methodReturningNSPoint) }.should raise_error(TypeError)
-=end
     lambda { o.methodAcceptingNSRange(nil) }.should raise_error(TypeError)
     lambda { o.methodAcceptingNSRange(123) }.should raise_error(TypeError)
     lambda { o.methodAcceptingNSRange(Object.new) }.should raise_error(TypeError)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090422/01d165a6/attachment.html>


More information about the macruby-changes mailing list