Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fix a const lookup bug in instance_eval, fix a deadlock when autoload…

…ing constants, fix a GC bug when passing thread-local objects to a new thread

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@3323 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
commit 97e44237ee1f157596fd3f7a831b1a61774e7d47 1 parent b2dc991
Laurent Sansonetti authored
View
5 dispatcher.cpp
@@ -436,6 +436,11 @@ __rb_vm_ruby_dispatch(VALUE top, VALUE self, SEL sel,
return ((VALUE (*)(VALUE, SEL, ...))node->ruby_imp)
(self, sel, rb_ary_new4(argc, argv));
}
+ else if (arity.real == 3) {
+ return ((VALUE (*)(VALUE, SEL, VALUE, int,
+ const VALUE *))node->ruby_imp)
+ (self, sel, top, argc, argv);
+ }
else {
printf("invalid negative arity for C function %d\n",
arity.real);
View
2  eval.c
@@ -506,8 +506,6 @@ rb_frame_callee(void)
* _mod_ or one of its ancestors. See also <code>Module#include</code>.
*/
-VALUE rb_make_singleton_class(VALUE super);
-
static VALUE
rb_mod_append_features(VALUE module, SEL sel, VALUE include)
{
View
1  include/ruby/intern.h
@@ -152,6 +152,7 @@ VALUE rb_objc_create_class(const char *name, VALUE super);
bool rb_objc_install_primitives(Class ocklass, Class ocsuper);
void rb_define_object_special_methods(VALUE klass);
VALUE rb_class_new_instance_imp(VALUE, SEL, int, VALUE *);
+VALUE rb_make_singleton_class(VALUE super);
#endif
VALUE rb_class_boot(VALUE);
VALUE rb_class_new(VALUE);
View
39 vm.cpp
@@ -1143,8 +1143,15 @@ rb_const_get_direct(VALUE klass, ID id)
VALUE value;
if (CFDictionaryGetValueIfPresent(iv_dict, (const void *)id,
(const void **)&value)) {
- if (value == Qundef && RTEST(rb_autoload_load(klass, id))) {
- goto retry;
+ if (value == Qundef) {
+ // Constant is a candidate for autoload. We must release the
+ // GIL before requiring the file and acquire it again.
+ GET_CORE()->unlock();
+ const bool autoloaded = RTEST(rb_autoload_load(klass, id));
+ GET_CORE()->lock();
+ if (autoloaded) {
+ goto retry;
+ }
}
return value;
}
@@ -1281,6 +1288,22 @@ rb_vm_get_outer(VALUE klass)
return o == NULL ? Qundef : (VALUE)o->klass;
}
+static VALUE
+get_klass_const(VALUE outer, ID path, bool lexical)
+{
+ if (lexical) {
+ if (rb_vm_const_lookup(outer, path, true, true) == Qtrue) {
+ return rb_vm_const_lookup(outer, path, true, false);
+ }
+ }
+ else {
+ if (rb_const_defined_at(outer, path)) {
+ return rb_const_get_at(outer, path);
+ }
+ }
+ return Qundef;
+}
+
extern "C"
VALUE
rb_vm_define_class(ID path, VALUE outer, VALUE super, int flags,
@@ -1296,10 +1319,9 @@ rb_vm_define_class(ID path, VALUE outer, VALUE super, int flags,
}
}
- VALUE klass;
- if (rb_const_defined_at(outer, path)) {
+ VALUE klass = get_klass_const(outer, path, dynamic_class);
+ if (klass != Qundef) {
// Constant is already defined.
- klass = rb_const_get_at(outer, path);
check_if_module(klass);
if (!(flags & DEFINE_MODULE) && super != 0) {
if (rb_class_real(RCLASS_SUPER(klass)) != super) {
@@ -4461,6 +4483,13 @@ rb_vm_thread_pre_init(rb_vm_thread_t *t, rb_vm_block_t *body, int argc,
if (body != NULL) {
GC_WB(&t->body, body);
rb_vm_block_make_detachable_proc(body);
+
+ // Remove the thread-local bit of all dynamic variables.
+ for (int i = 0; i < body->dvars_size; i++) {
+ VALUE *dvar = body->dvars[i];
+ GC_RETAIN(*dvar);
+ GC_RELEASE(*dvar);
+ }
}
else {
t->body = NULL;
View
3  vm.h
@@ -231,6 +231,9 @@ rb_vm_node_arity(NODE *node)
else if (argc == -2) {
arity.real = 1;
}
+ else if (argc == -3) {
+ arity.real = 3;
+ }
else {
printf("invalid FBODY arity: %d\n", argc);
abort();
View
31 vm_eval.c
@@ -501,7 +501,7 @@ rb_eval_cmd(VALUE cmd, VALUE arg, int level)
*/
static VALUE
-rb_obj_instance_eval(VALUE self, SEL sel, int argc, VALUE *argv)
+rb_obj_instance_eval(VALUE self, SEL sel, VALUE top, int argc, VALUE *argv)
{
VALUE klass;
@@ -509,7 +509,30 @@ rb_obj_instance_eval(VALUE self, SEL sel, int argc, VALUE *argv)
klass = 0;
}
else {
- klass = rb_singleton_class(self);
+ switch (TYPE(self)) {
+#if 0
+ case T_CLASS:
+ case T_MODULE:
+ if (RCLASS_RUBY(self)) {
+ VALUE sself = rb_make_singleton_class(RCLASS_SUPER(self));
+ RCLASS_SET_SUPER(self, sself);
+ self = sself;
+ }
+ else {
+ klass = rb_singleton_class(self);
+ break;
+ }
+ // fall through
+#endif
+ default:
+ klass = rb_singleton_class(self);
+ switch (TYPE(top)) {
+ case T_CLASS:
+ case T_MODULE:
+ rb_vm_set_outer(klass, top);
+ break;
+ }
+ }
}
return specific_eval(argc, argv, klass, self);
}
@@ -759,12 +782,12 @@ Init_vm_eval(void)
rb_objc_define_module_function(rb_mKernel, "loop", rb_f_loop, 0);
- rb_objc_define_method(rb_cNSObject, "instance_eval", rb_obj_instance_eval, -1);
+ rb_objc_define_method(rb_cNSObject, "instance_eval", rb_obj_instance_eval, -3);
rb_objc_define_method(rb_cNSObject, "instance_exec", rb_obj_instance_exec, -1);
rb_objc_define_private_method(rb_cNSObject, "method_missing", rb_method_missing, -1);
rb_objc_define_method(rb_cNSObject, "__send__", rb_f_send, -1);
- rb_objc_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
+ rb_objc_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -3);
rb_objc_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
rb_objc_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
rb_objc_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
Please sign in to comment.
Something went wrong with that request. Please try again.