[macruby-changes] [1546] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Wed May 6 17:21:24 PDT 2009
Revision: 1546
http://trac.macosforge.org/projects/ruby/changeset/1546
Author: lsansonetti at apple.com
Date: 2009-05-06 17:21:24 -0700 (Wed, 06 May 2009)
Log Message:
-----------
fixed yield of splat args, yield_spec.rb is now green
Modified Paths:
--------------
MacRuby/branches/experimental/rakelib/spec.rake
MacRuby/branches/experimental/roxor.cpp
Removed Paths:
-------------
MacRuby/branches/experimental/spec/frozen/tags/macruby/language/yield_tags.txt
Modified: MacRuby/branches/experimental/rakelib/spec.rake
===================================================================
--- MacRuby/branches/experimental/rakelib/spec.rake 2009-05-06 21:08:47 UTC (rev 1545)
+++ MacRuby/branches/experimental/rakelib/spec.rake 2009-05-07 00:21:24 UTC (rev 1546)
@@ -26,6 +26,7 @@
symbol
unless
until
+ yield
while
}
Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp 2009-05-06 21:08:47 UTC (rev 1545)
+++ MacRuby/branches/experimental/roxor.cpp 2009-05-07 00:21:24 UTC (rev 1546)
@@ -4854,31 +4854,15 @@
"rb_vm_yield_args", ft));
}
- std::vector<Value *>params;
-
- if (node->nd_head == NULL) {
- params.push_back(ConstantInt::get(Type::Int32Ty, 0));
+ std::vector<Value *> params;
+ int argc = 0;
+ if (node->nd_head != NULL) {
+ compile_dispatch_arguments(node->nd_head, params, &argc);
}
- else {
- NODE *args = node->nd_head;
- const int argc = args->nd_alen;
- params.push_back(ConstantInt::get(Type::Int32Ty, argc));
- for (int i = 0; i < argc; i++) {
- params.push_back(compile_node(args->nd_head));
- args = args->nd_next;
- }
- }
-#if 0 // TODO
- else {
- params.push_back(ConstantInt::get(Type::Int32Ty, 1));
- params.push_back(splatArgFollowsVal);
- params.push_back(compile_node(args->nd_head));
- }
-#endif
+ params.insert(params.begin(), ConstantInt::get(Type::Int32Ty, argc));
return CallInst::Create(yieldFunc, params.begin(),
params.end(), "", bb);
-
}
break;
@@ -7120,54 +7104,61 @@
}
__attribute__((always_inline))
-static VALUE
-__rb_vm_bcall(VALUE self, VALUE dvars, rb_vm_block_t *b,
- IMP pimp, const rb_vm_arity_t &arity, int argc, const VALUE *argv)
+static void
+__rb_vm_fix_args(const VALUE *argv, VALUE *new_argv, const rb_vm_arity_t &arity, int argc)
{
- if ((arity.real != argc) || (arity.max == -1)) {
- VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * arity.real);
- assert(argc >= arity.min);
- assert((arity.max == -1) || (argc <= arity.max));
- int used_opt_args = argc - arity.min;
- int opt_args, rest_pos;
- if (arity.max == -1) {
- opt_args = arity.real - arity.min - 1;
- rest_pos = arity.left_req + opt_args;
+ assert(argc >= arity.min);
+ assert((arity.max == -1) || (argc <= arity.max));
+ int used_opt_args = argc - arity.min;
+ int opt_args, rest_pos;
+ if (arity.max == -1) {
+ opt_args = arity.real - arity.min - 1;
+ rest_pos = arity.left_req + opt_args;
+ }
+ else {
+ opt_args = arity.real - arity.min;
+ rest_pos = -1;
+ }
+ for (int i = 0; i < arity.real; ++i) {
+ if (i < arity.left_req) {
+ // required args before optional args
+ new_argv[i] = argv[i];
}
- else {
- opt_args = arity.real - arity.min;
- rest_pos = -1;
- }
- for (int i = 0; i < arity.real; ++i) {
- if (i < arity.left_req) {
- // required args before optional args
+ else if (i < arity.left_req + opt_args) {
+ // optional args
+ int opt_arg_index = i - arity.left_req;
+ if (opt_arg_index >= used_opt_args) {
+ new_argv[i] = Qundef;
+ }
+ else {
new_argv[i] = argv[i];
}
- else if (i < arity.left_req + opt_args) {
- // optional args
- int opt_arg_index = i - arity.left_req;
- if (opt_arg_index >= used_opt_args) {
- new_argv[i] = Qundef;
- }
- else {
- new_argv[i] = argv[i];
- }
+ }
+ else if (i == rest_pos) {
+ // rest
+ int rest_size = argc - arity.real + 1;
+ if (rest_size <= 0) {
+ new_argv[i] = rb_ary_new();
}
- else if (i == rest_pos) {
- // rest
- int rest_size = argc - arity.real + 1;
- if (rest_size <= 0) {
- new_argv[i] = rb_ary_new();
- }
- else {
- new_argv[i] = rb_ary_new4(rest_size, &argv[i]);
- }
- }
else {
- // required args after optional args
- new_argv[i] = argv[argc-(arity.real - i)];
+ new_argv[i] = rb_ary_new4(rest_size, &argv[i]);
}
}
+ else {
+ // required args after optional args
+ new_argv[i] = argv[argc-(arity.real - i)];
+ }
+ }
+}
+
+__attribute__((always_inline))
+static VALUE
+__rb_vm_bcall(VALUE self, VALUE dvars, rb_vm_block_t *b,
+ IMP pimp, const rb_vm_arity_t &arity, int argc, const VALUE *argv)
+{
+ if ((arity.real != argc) || (arity.max == -1)) {
+ VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * arity.real);
+ __rb_vm_fix_args(argv, new_argv, arity, argc);
argv = new_argv;
argc = arity.real;
}
@@ -7209,48 +7200,7 @@
{
if ((arity.real != argc) || (arity.max == -1)) {
VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * arity.real);
- assert(argc >= arity.min);
- assert((arity.max == -1) || (argc <= arity.max));
- int used_opt_args = argc - arity.min;
- int opt_args, rest_pos;
- if (arity.max == -1) {
- opt_args = arity.real - arity.min - 1;
- rest_pos = arity.left_req + opt_args;
- }
- else {
- opt_args = arity.real - arity.min;
- rest_pos = -1;
- }
- for (int i = 0; i < arity.real; ++i) {
- if (i < arity.left_req) {
- // required args before optional args
- new_argv[i] = argv[i];
- }
- else if (i < arity.left_req + opt_args) {
- // optional args
- int opt_arg_index = i - arity.left_req;
- if (opt_arg_index >= used_opt_args) {
- new_argv[i] = Qundef;
- }
- else {
- new_argv[i] = argv[i];
- }
- }
- else if (i == rest_pos) {
- // rest
- int rest_size = argc - arity.real + 1;
- if (rest_size <= 0) {
- new_argv[i] = rb_ary_new();
- }
- else {
- new_argv[i] = rb_ary_new4(rest_size, &argv[i]);
- }
- }
- else {
- // required args after optional args
- new_argv[i] = argv[argc-(arity.real - i)];
- }
- }
+ __rb_vm_fix_args(argv, new_argv, arity, argc);
argv = new_argv;
argc = arity.real;
}
@@ -7800,51 +7750,60 @@
abort();
}
+#define MAX_DISPATCH_ARGS 200
+
+__attribute__((always_inline))
+static int
+__rb_vm_resolve_args(VALUE *argv, int argc, va_list ar)
+{
+ // TODO we should only determine the real argc here (by taking into
+ // account the length splat arguments) and do the real unpacking of
+ // splat arguments in __rb_vm_rcall(). This way we can optimize more
+ // things (for ex. no need to unpack splats that are passed as a splat
+ // argument in the method being called!).
+ int i, real_argc = 0;
+ bool splat_arg_follows = false;
+ for (i = 0; i < argc; i++) {
+ VALUE arg = va_arg(ar, VALUE);
+ if (arg == SPLAT_ARG_FOLLOWS) {
+ splat_arg_follows = true;
+ i--;
+ }
+ else {
+ if (splat_arg_follows) {
+ VALUE ary = rb_check_convert_type(arg, T_ARRAY, "Array",
+ "to_a");
+ if (NIL_P(ary)) {
+ ary = rb_ary_new3(1, arg);
+ }
+ int j, count = RARRAY_LEN(ary);
+ assert(real_argc + count < MAX_DISPATCH_ARGS);
+ for (j = 0; j < count; j++) {
+ argv[real_argc++] = RARRAY_AT(ary, j);
+ }
+ splat_arg_follows = false;
+ }
+ else {
+ assert(real_argc < MAX_DISPATCH_ARGS);
+ argv[real_argc++] = arg;
+ }
+ }
+ }
+
+ return real_argc;
+}
+
extern "C"
VALUE
rb_vm_dispatch(struct mcache *cache, VALUE self, SEL sel, rb_vm_block_t *block,
unsigned char opt, int argc, ...)
{
-#define MAX_DISPATCH_ARGS 200
VALUE argv[MAX_DISPATCH_ARGS];
if (argc > 0) {
- // TODO we should only determine the real argc here (by taking into
- // account the length splat arguments) and do the real unpacking of
- // splat arguments in __rb_vm_rcall(). This way we can optimize more
- // things (for ex. no need to unpack splats that are passed as a splat
- // argument in the method being called!).
va_list ar;
va_start(ar, argc);
- int i, real_argc = 0;
- bool splat_arg_follows = false;
- for (i = 0; i < argc; i++) {
- VALUE arg = va_arg(ar, VALUE);
- if (arg == SPLAT_ARG_FOLLOWS) {
- splat_arg_follows = true;
- i--;
- }
- else {
- if (splat_arg_follows) {
- VALUE ary = rb_check_convert_type(arg, T_ARRAY, "Array",
- "to_a");
- if (NIL_P(ary)) {
- ary = rb_ary_new3(1, arg);
- }
- int j, count = RARRAY_LEN(ary);
- assert(real_argc + count < MAX_DISPATCH_ARGS);
- for (j = 0; j < count; j++) {
- argv[real_argc++] = RARRAY_AT(ary, j);
- }
- splat_arg_follows = false;
- }
- else {
- assert(real_argc < MAX_DISPATCH_ARGS);
- argv[real_argc++] = arg;
- }
- }
- }
+ argc = __rb_vm_resolve_args(argv, argc, ar);
va_end(ar);
- argc = real_argc;
}
rb_vm_block_t *b = (rb_vm_block_t *)block;
@@ -8480,14 +8439,11 @@
VALUE
rb_vm_yield_args(int argc, ...)
{
- VALUE *argv = NULL;
+ VALUE argv[MAX_DISPATCH_ARGS];
if (argc > 0) {
va_list ar;
va_start(ar, argc);
- argv = (VALUE *)alloca(sizeof(VALUE) * argc);
- for (int i = 0; i < argc; ++i) {
- argv[i] = va_arg(ar, VALUE);
- }
+ argc = __rb_vm_resolve_args(argv, argc, ar);
va_end(ar);
}
return rb_vm_yield0(argc, argv);
Deleted: MacRuby/branches/experimental/spec/frozen/tags/macruby/language/yield_tags.txt
===================================================================
--- MacRuby/branches/experimental/spec/frozen/tags/macruby/language/yield_tags.txt 2009-05-06 21:08:47 UTC (rev 1545)
+++ MacRuby/branches/experimental/spec/frozen/tags/macruby/language/yield_tags.txt 2009-05-07 00:21:24 UTC (rev 1546)
@@ -1,4 +0,0 @@
-fails:Assignment via yield assigns splatted objects to block variables
-fails:Assignment via yield assigns splatted objects to block variables
-fails:Assignment via yield assigns objects to splatted block variables that include the splat operator inside the block
-fails:Assignment via yield assigns splatted objects to multiple block variables
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090506/51186021/attachment-0001.html>
More information about the macruby-changes
mailing list