Permalink
Browse files

implemented Method#to_proc, fixed Hash.new{}

  • Loading branch information...
1 parent 22ac117 commit 792d1addcca808d7a5ac8a35dd6ad38cfe536040 @lrz lrz committed May 15, 2009
Showing with 44 additions and 11 deletions.
  1. +9 −1 hash.c
  2. +1 −0 id.c
  3. +1 −0 id.h
  4. +1 −0 include/ruby/intern.h
  5. +0 −4 proc.c
  6. +32 −6 roxor.cpp
View
10 hash.c
@@ -279,7 +279,7 @@ rb_hash_modify_check(VALUE hash)
*/
static VALUE
-rb_hash_initialize(VALUE hash, SEL sel, int argc, VALUE *argv)
+rb_hash_initialize(VALUE hash, SEL sel, int argc, const VALUE *argv)
{
VALUE ifnone;
@@ -300,6 +300,14 @@ rb_hash_initialize(VALUE hash, SEL sel, int argc, VALUE *argv)
return hash;
}
+VALUE
+rb_hash_new2(int argc, const VALUE *argv)
+{
+ VALUE h = hash_alloc(0);
+ rb_hash_initialize(h, 0, argc, argv);
+ return h;
+}
+
/*
* call-seq:
* Hash[ [key =>|, value]* ] => hash
View
1 id.c
@@ -64,6 +64,7 @@ Init_id(void)
selInit = sel_registerName("init");
selInitialize = sel_registerName("initialize");
selInitialize2 = sel_registerName("initialize:");
+ selNew = sel_registerName("new");
selRespondTo = sel_registerName("respond_to?:");
selMethodMissing = sel_registerName("method_missing:");
selCopy = sel_registerName("copy");
View
1 id.h
@@ -74,6 +74,7 @@ extern SEL selAlloc;
extern SEL selInit;
extern SEL selInitialize;
extern SEL selInitialize2;
+extern SEL selNew;
extern SEL selRespondTo;
extern SEL selMethodMissing;
extern SEL selCopy;
View
@@ -361,6 +361,7 @@ void st_foreach_safe(struct st_table *, int (*)(ANYARGS), st_data_t);
void rb_hash_foreach(VALUE, int (*)(ANYARGS), VALUE);
VALUE rb_hash(VALUE);
VALUE rb_hash_new(void);
+VALUE rb_hash_new2(int argc, const VALUE *argv);
VALUE rb_hash_dup(VALUE);
VALUE rb_hash_freeze(VALUE);
VALUE rb_hash_aref(VALUE, VALUE);
View
4 proc.c
@@ -1384,14 +1384,10 @@ rb_proc_new(
static VALUE
method_proc(VALUE method, SEL sel)
{
-#if 0
- // TODO
rb_vm_method_t *data;
Data_Get_Struct(method, rb_vm_method_t, data);
rb_vm_block_t *block = rb_vm_create_block_from_method(data);
return rb_proc_alloc_with_block(rb_cProc, block);
-#endif
- return Qnil;
}
/*
View
@@ -7880,7 +7880,25 @@ __rb_vm_dispatch(struct mcache *cache, VALUE self, Class klass, SEL sel,
goto recache;
}
- if (sel == selClass) {
+ if (block != NULL) {
+ if (self == rb_cNSMutableHash && sel == selNew) {
+ // Because Hash.new can accept a block.
+ GET_VM()->add_current_block(block);
+ VALUE h = Qnil;
+ try {
+ h = rb_hash_new2(argc, argv);
+ }
+ catch (...) {
+ GET_VM()->pop_current_block();
+ throw;
+ }
+ GET_VM()->pop_current_block();
+ return h;
+ }
+ rb_warn("passing a block to an Objective-C method - " \
+ "will be ignored");
+ }
+ else if (sel == selClass) {
// Because +[NSObject class] returns self.
if (RCLASS_META(klass)) {
return RCLASS_MODULE(self) ? rb_cModule : rb_cClass;
@@ -8152,7 +8170,7 @@ rb_vm_prepare_block(void *llvm_function, NODE *node, VALUE self,
}
std::map<NODE *, rb_vm_block_t *>::iterator iter =
- GET_VM()->blocks.find(node);
+ GET_VM()->blocks.find(cache_key);
rb_vm_block_t *b;
bool cached = false;
@@ -8532,8 +8550,9 @@ rb_vm_create_block_from_method(rb_vm_method_t *method)
GC_WB(&b->self, method->recv);
b->node = method->node;
- b->arity = rb_vm_node_arity(method->node);
- b->imp = NULL; // TODO
+ b->arity = method->node == NULL
+ ? rb_vm_arity(method->arity) : rb_vm_node_arity(method->node);
+ b->imp = (IMP)method;
b->flags = VM_BLOCK_PROC | VM_BLOCK_METHOD;
b->locals = NULL;
b->parent_var_uses = NULL;
@@ -8608,8 +8627,15 @@ rb_vm_block_eval0(rb_vm_block_t *b, int argc, const VALUE *argv)
b->flags |= VM_BLOCK_ACTIVE;
VALUE v = Qnil;
try {
- v = __rb_vm_bcall(b->self, (VALUE)b->dvars, b, b->imp, b->arity,
- argc, argv);
+ if (b->flags & VM_BLOCK_METHOD) {
+ rb_vm_method_t *m = (rb_vm_method_t *)b->imp;
+ v = rb_vm_call_with_cache2(m->cache, NULL, m->recv, m->oclass,
+ m->sel, argc, argv);
+ }
+ else {
+ v = __rb_vm_bcall(b->self, (VALUE)b->dvars, b, b->imp, b->arity,
+ argc, argv);
+ }
}
catch (...) {
b->flags &= ~VM_BLOCK_ACTIVE;

0 comments on commit 792d1ad

Please sign in to comment.