[macruby-changes] [4882] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Nov 4 19:06:15 PDT 2010
Revision: 4882
http://trac.macosforge.org/projects/ruby/changeset/4882
Author: lsansonetti at apple.com
Date: 2010-11-04 19:06:13 -0700 (Thu, 04 Nov 2010)
Log Message:
-----------
add support for C-style arrays (from/to Ruby)
Modified Paths:
--------------
MacRuby/trunk/compiler.cpp
MacRuby/trunk/compiler.h
MacRuby/trunk/kernel.c
Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp 2010-11-04 18:17:48 UTC (rev 4881)
+++ MacRuby/trunk/compiler.cpp 2010-11-05 02:06:13 UTC (rev 4882)
@@ -196,6 +196,8 @@
dupArrayFunc = get_function("vm_ary_dup");
newArrayFunc = get_function("vm_rary_new");
asetArrayFunc = get_function("vm_rary_aset");
+ entryArrayFunc = get_function("vm_ary_entry");
+ checkArrayFunc = get_function("vm_ary_check");
newStructFunc = NULL;
newOpaqueFunc = NULL;
newPointerFunc = NULL;
@@ -5336,6 +5338,42 @@
return new BitCastInst(f, PtrTy, "", bb);
}
+static void
+decompose_ary_type(const char *type, long *size_p, char *elem_type_p,
+ const size_t elem_type_len)
+{
+ // Syntax is [8S] for `short foo[8]'.
+ // First, let's grab the size.
+ char buf[100];
+ unsigned int n = 0;
+ const char *p = type + 1;
+ while (isdigit(*p)) {
+ assert(n < (sizeof buf) - 1);
+ buf[n++] = *p;
+ p++;
+ }
+ assert(n > 0);
+ buf[n] = '\0';
+ const long size = atol(buf);
+ assert(size > 0);
+ if (size_p != NULL) {
+ *size_p = size;
+ }
+
+ // Second, the element type.
+ n = 0;
+ while (*p != _C_ARY_E) {
+ assert(n < (sizeof buf) - 1);
+ buf[n++] = *p;
+ p++;
+ }
+ assert(n > 0);
+ buf[n] = '\0';
+ if (elem_type_p != NULL) {
+ strlcpy(elem_type_p, buf, elem_type_len);
+ }
+}
+
Value *
RoxorCompiler::compile_conversion_to_c(const char *type, Value *val,
Value *slot)
@@ -5506,6 +5544,40 @@
return compile_get_cptr(val, type, slot);
}
break;
+
+ case _C_ARY_B:
+ {
+ const ArrayType *ary_type = cast<ArrayType>(convert_type(type));
+ const Type *elem_type = ary_type->getElementType();
+ const unsigned elem_count = ary_type->getNumElements();
+
+ char elem_c_type[100];
+ decompose_ary_type(type, NULL, elem_c_type,
+ sizeof elem_c_type);
+
+ Value *elem_count_val = ConstantInt::get(Int32Ty, elem_count);
+ Value *args[] = {
+ val,
+ elem_count_val
+ };
+ val = CallInst::Create(checkArrayFunc, args, args + 2, "", bb);
+ Value *ary = new AllocaInst(elem_type, elem_count_val, "", bb);
+ for (unsigned i = 0; i < elem_count; i++) {
+ Value *idx = ConstantInt::get(Int32Ty, i);
+ Value *args[] = {
+ val,
+ idx
+ };
+ Value *elem = CallInst::Create(entryArrayFunc,
+ args, args + 2, "", bb);
+ Value *slot = GetElementPtrInst::Create(ary, idx, "", bb);
+ compile_conversion_to_c(elem_c_type, elem, slot);
+ }
+
+ return new BitCastInst(ary, PointerType::getUnqual(ary_type),
+ "", bb);
+ }
+ break;
}
if (func == NULL) {
@@ -5745,7 +5817,35 @@
return compile_new_pointer(type + 1, val);
}
- break;
+ break;
+
+ case _C_ARY_B:
+ {
+ long elem_count = 0;
+ char elem_c_type[100];
+ decompose_ary_type(type, &elem_count, elem_c_type,
+ sizeof elem_c_type);
+ const Type *elem_type = convert_type(elem_c_type);
+
+ val = new BitCastInst(val, PointerType::getUnqual(elem_type),
+ "", bb);
+
+ Value *ary = CallInst::Create(newArrayFunc,
+ ConstantInt::get(Int32Ty, elem_count), "", bb);
+ for (long i = 0; i < elem_count; i++) {
+ Value *idx = ConstantInt::get(Int32Ty, i);
+ Value *slot = GetElementPtrInst::Create(val, idx, "", bb);
+ Value *elem = new LoadInst(slot, "", bb);
+ Value *args[] = {
+ ary,
+ idx,
+ compile_conversion_to_ruby(elem_c_type, elem_type, elem)
+ };
+ CallInst::Create(asetArrayFunc, args, args + 3, "", bb);
+ }
+ return ary;
+ }
+ break;
}
if (func == NULL) {
@@ -5819,29 +5919,9 @@
case _C_ARY_B:
{
- // Syntax is [8S] for `short foo[8]'.
- // First, let's grab the size.
char buf[100];
- unsigned int n = 0;
- const char *p = type + 1;
- while (isdigit(*p)) {
- assert(n < (sizeof buf) - 1);
- buf[n++] = *p;
- p++;
- }
- assert(n > 0);
- buf[n] = '\0';
- const long size = atol(buf);
- assert(size > 0);
- // Second, the element type.
- n = 0;
- while (*p != _C_ARY_E) {
- assert(n < (sizeof buf) - 1);
- buf[n++] = *p;
- p++;
- }
- assert(n > 0);
- buf[n] = '\0';
+ long size = 0;
+ decompose_ary_type(type, &size, buf, sizeof buf);
const Type *type = convert_type(buf);
// Now, we can return the array type.
return ArrayType::get(type, size);
@@ -5969,6 +6049,10 @@
f_type = PointerType::getUnqual(llvm_type);
byval_args.push_back(f_types.size() + 1 /* retval */);
}
+ else if (ArrayType::classof(llvm_type)) {
+ // Vectors are passed by reference.
+ f_type = PointerType::getUnqual(llvm_type);
+ }
if (!stop_arg_type) {
// In order to conform to the ABI, we must stop providing types
@@ -6353,6 +6437,10 @@
t = PointerType::getUnqual(t);
byval_args.push_back(f_types.size() + 1 /* retval */);
}
+ else if (ArrayType::classof(t)) {
+ // Vectors are passed by reference.
+ t = PointerType::getUnqual(t);
+ }
f_types.push_back(t);
arg_types.push_back(buf);
}
Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h 2010-11-04 18:17:48 UTC (rev 4881)
+++ MacRuby/trunk/compiler.h 2010-11-05 02:06:13 UTC (rev 4882)
@@ -186,6 +186,8 @@
Function *dupArrayFunc;
Function *newArrayFunc;
Function *asetArrayFunc;
+ Function *entryArrayFunc;
+ Function *checkArrayFunc;
Function *newStructFunc;
Function *newOpaqueFunc;
Function *newPointerFunc;
Modified: MacRuby/trunk/kernel.c
===================================================================
--- MacRuby/trunk/kernel.c 2010-11-04 18:17:48 UTC (rev 4881)
+++ MacRuby/trunk/kernel.c 2010-11-05 02:06:13 UTC (rev 4882)
@@ -925,6 +925,26 @@
}
PRIMITIVE VALUE
+vm_ary_check(VALUE obj, int size)
+{
+ VALUE ary = rb_check_convert_type(obj, T_ARRAY, "Array", "to_ary");
+ if (NIL_P(ary)) {
+ rb_raise(rb_eTypeError, "expected Array");
+ }
+ if (RARRAY_LEN(ary) != size) {
+ rb_raise(rb_eArgError, "expected Array of size %d, got %ld",
+ size, RARRAY_LEN(ary));
+ }
+ return ary;
+}
+
+PRIMITIVE VALUE
+vm_ary_entry(VALUE ary, int i)
+{
+ return rb_ary_entry(ary, i);
+}
+
+PRIMITIVE VALUE
vm_rary_new(int len)
{
VALUE ary = rb_ary_new2(len);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101104/e721b17b/attachment-0001.html>
More information about the macruby-changes
mailing list