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

source_changes at macosforge.org source_changes at macosforge.org
Wed Apr 22 22:38:30 PDT 2009


Revision: 1476
          http://trac.macosforge.org/projects/ruby/changeset/1476
Author:   lsansonetti at apple.com
Date:     2009-04-22 22:38:29 -0700 (Wed, 22 Apr 2009)
Log Message:
-----------
finished struct #new (I think)

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

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-04-23 02:13:18 UTC (rev 1475)
+++ MacRuby/branches/experimental/roxor.cpp	2009-04-23 05:38:29 UTC (rev 1476)
@@ -265,6 +265,7 @@
 	Function *newArrayFunc;
 	Function *newStructFunc;
 	Function *getStructFieldsFunc;
+	Function *checkArityFunc;
 	Function *newRangeFunc;
 	Function *newRegexpFunc;
 	Function *strInternFunc;
@@ -346,9 +347,10 @@
 	void compile_landing_pad_footer(void);
 	void compile_rethrow_exception(void);
 	Value *compile_lvar_slot(ID name);
-	Value *compile_new_struct(VALUE klass, std::vector<Value *> &fields);
+	Value *compile_new_struct(Value *klass, std::vector<Value *> &fields);
 	void compile_get_struct_fields(Value *val, Value *buf,
 		rb_vm_bs_boxed_t *bs_boxed);
+	void compile_check_arity(Value *given, Value *requested);
 
 	Value *compile_conversion_to_c(const char *type, Value *val,
 				       Value *slot);
@@ -593,6 +595,10 @@
 	    return NULL;
 	}
 
+	size_t get_sizeof(const Type *type) {
+	    return ee->getTargetData()->getTypeSizeInBits(type) / 8;
+	}
+
 	bool is_large_struct_type(const Type *type) {
 	    return type->getTypeID() == Type::StructTyID
 		&& ee->getTargetData()->getTypeSizeInBits(type) > 128;
@@ -654,6 +660,7 @@
     newArrayFunc = NULL;
     newStructFunc = NULL;
     getStructFieldsFunc = NULL;
+    checkArityFunc = NULL;
     newRangeFunc = NULL;
     newRegexpFunc = NULL;
     strInternFunc = NULL;
@@ -5309,7 +5316,7 @@
 }
 
 Value *
-RoxorCompiler::compile_new_struct(VALUE klass, std::vector<Value *> &fields)
+RoxorCompiler::compile_new_struct(Value *klass, std::vector<Value *> &fields)
 {
     if (newStructFunc == NULL) {
 	std::vector<const Type *> types;
@@ -5321,9 +5328,9 @@
 		    "rb_vm_new_struct", ft));
     }
 
-    fields.insert(fields.begin(),
-	    ConstantInt::get(Type::Int32Ty, fields.size()));
-    fields.insert(fields.begin(), ConstantInt::get(RubyObjTy, klass));
+    Value *argc = ConstantInt::get(Type::Int32Ty, fields.size());
+    fields.insert(fields.begin(), argc);
+    fields.insert(fields.begin(), klass);
 
     return CallInst::Create(newStructFunc, fields.begin(), fields.end(),
 	    "", bb); 
@@ -5415,7 +5422,8 @@
 				llvm_ftype, fval));
 		}
 
-		return compile_new_struct(bs_boxed->klass, params);
+		Value *klass = ConstantInt::get(RubyObjTy, bs_boxed->klass);
+		return compile_new_struct(klass, params);
 	    }
 	    break;
     }
@@ -8299,6 +8307,33 @@
     return v;
 }
 
+extern "C"
+void
+rb_vm_check_arity(int given, int requested)
+{
+    if (given != requested) {
+	rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
+		given, requested);
+    }
+}
+
+void
+RoxorCompiler::compile_check_arity(Value *given, Value *requested)
+{
+    if (checkArityFunc == NULL) {
+	// void rb_vm_check_arity(int given, int requested);
+	checkArityFunc = cast<Function>(module->getOrInsertFunction(
+		    "rb_vm_check_arity",
+		    Type::VoidTy, Type::Int32Ty, Type::Int32Ty, NULL));
+    }
+
+    std::vector<Value *> params;
+    params.push_back(given);
+    params.push_back(requested);
+
+    compile_protected_call(checkArityFunc, params);
+}
+
 Function *
 RoxorCompiler::compile_bs_struct_new(rb_vm_bs_boxed_t *bs_boxed)
 {
@@ -8306,16 +8341,75 @@
 		RubyObjTy, RubyObjTy, PtrTy, Type::Int32Ty, RubyObjPtrTy,
 		NULL));
     Function::arg_iterator arg = f->arg_begin();
-    ++arg; // skip recv
-    ++arg; // skip sel
-    //Value *argv = arg;
+    Value *klass = arg++; 	// self
+    arg++;			// sel
+    Value *argc = arg++; 	// argc
+    Value *argv = arg++; 	// argv
 
     bb = BasicBlock::Create("EntryBlock", f);
 
-    // TODO
+    BasicBlock *no_args_bb = BasicBlock::Create("no_args", f);
+    BasicBlock *args_bb  = BasicBlock::Create("args", f);
+    Value *has_args = new ICmpInst(ICmpInst::ICMP_EQ, argc,
+	    ConstantInt::get(Type::Int32Ty, 0), "", bb);
 
-    ReturnInst::Create(nilVal, bb);
+    BranchInst::Create(no_args_bb, args_bb, has_args, bb);
 
+    // No arguments are given, let's create Ruby field objects based on a
+    // zero-filled memory slot.
+    bb = no_args_bb;
+    std::vector<Value *> fields;
+
+    for (unsigned i = 0; i < bs_boxed->as.s->fields_count; i++) {
+	const char *ftype = bs_boxed->as.s->fields[i].type;
+	const Type *llvm_type = convert_type(ftype);
+	Value *fval = new AllocaInst(llvm_type, "", bb);
+
+	const Type *Tys[] = { IntTy };
+	Function *memset_func = Intrinsic::getDeclaration(module,
+		Intrinsic::memset, Tys, 1);
+	assert(memset_func != NULL);
+
+	std::vector<Value *> params;
+	params.push_back(new BitCastInst(fval, PtrTy, "", bb));
+	params.push_back(ConstantInt::get(Type::Int8Ty, 0));
+	params.push_back(ConstantInt::get(IntTy,
+		    GET_VM()->get_sizeof(llvm_type)));
+	params.push_back(ConstantInt::get(Type::Int32Ty, 0));
+	CallInst::Create(memset_func, params.begin(), params.end(), "", bb);
+
+	fval = new LoadInst(fval, "", bb);
+	fval = compile_conversion_to_ruby(ftype, llvm_type, fval);
+
+	fields.push_back(fval);
+    }
+
+    ReturnInst::Create(compile_new_struct(klass, fields), bb);
+
+    // Arguments are given. Need to check given arity, then convert the given
+    // Ruby values into the requested struct field types.
+    bb = args_bb;
+    fields.clear();
+
+    compile_check_arity(argc,
+	    ConstantInt::get(Type::Int32Ty, bs_boxed->as.s->fields_count));
+
+    for (unsigned i = 0; i < bs_boxed->as.s->fields_count; i++) {
+	const char *ftype = bs_boxed->as.s->fields[i].type;
+	const Type *llvm_type = convert_type(ftype);
+	Value *fval = new AllocaInst(llvm_type, "", bb);
+
+	Value *index = ConstantInt::get(Type::Int32Ty, i);
+	Value *arg = GetElementPtrInst::Create(argv, index, "", bb);
+	arg = new LoadInst(arg, "", bb);
+	arg = compile_conversion_to_c(ftype, arg, fval);
+	arg = compile_conversion_to_ruby(ftype, llvm_type, arg);
+
+	fields.push_back(arg);
+    }
+
+    ReturnInst::Create(compile_new_struct(klass, fields), bb);
+
     return f;
 }
 

Modified: MacRuby/branches/experimental/spec/macruby/struct_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/struct_spec.rb	2009-04-23 02:13:18 UTC (rev 1475)
+++ MacRuby/branches/experimental/spec/macruby/struct_spec.rb	2009-04-23 05:38:29 UTC (rev 1476)
@@ -43,8 +43,8 @@
     o.y.class.should == Float
     o.y.should == 2.0
 
-    fix1 = Object.new; def fix1.to_i; 1; end
-    fix2 = Object.new; def fix2.to_i; 2; end
+    fix1 = Object.new; def fix1.to_f; 1.0; end
+    fix2 = Object.new; def fix2.to_f; 2.0; end
 
     o = NSPoint.new(fix1, fix2)
     o.x.class.should == Float
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090422/8bcf65fc/attachment-0001.html>


More information about the macruby-changes mailing list