Revision: 3955 http://trac.macosforge.org/projects/ruby/changeset/3955 Author: lsansonetti@apple.com Date: 2010-04-21 21:22:47 -0700 (Wed, 21 Apr 2010) Log Message: ----------- when re-typing methods, do not re-type the same method twice and make sure the new signature matches the ruby arity Modified Paths: -------------- MacRuby/trunk/dispatcher.cpp MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/dispatcher.cpp =================================================================== --- MacRuby/trunk/dispatcher.cpp 2010-04-22 01:54:06 UTC (rev 3954) +++ MacRuby/trunk/dispatcher.cpp 2010-04-22 04:22:47 UTC (rev 3955) @@ -522,7 +522,7 @@ return false; } - GET_CORE()->retype_method(klass, node, types); + GET_CORE()->retype_method(klass, node, method_getTypeEncoding(m), types); return true; } Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2010-04-22 01:54:06 UTC (rev 3954) +++ MacRuby/trunk/vm.cpp 2010-04-22 04:22:47 UTC (rev 3955) @@ -1942,22 +1942,39 @@ rb_vm_method_node_t * RoxorCore::retype_method(Class klass, rb_vm_method_node_t *node, - const char *types) + const char *old_types, const char *new_types) { + if (strcmp(old_types, new_types) == 0) { + // No need to retype. + // XXX might be better to compare every type after filtering stack + // size and other crappy modifiers. + return node; + } + + const int new_types_arity = TypeArity(new_types); + char buf[100]; + if (node->arity.real + 3 >= new_types_arity) { + // The method arity is bigger than the number of types of the new + // signature, so we need to pad. + strlcpy(buf, new_types, sizeof buf); + for (int i = 0; i < node->arity.real + 3 - new_types_arity; i++) { + strlcat(buf, "@", sizeof buf); + } + new_types = &buf[0]; + } + RoxorCoreLock lock; - // TODO: 1) don't reinstall method in case the types didn't change - // 2) free LLVM machine code from old objc IMP - // Re-generate ObjC stub. Function *objc_func = RoxorCompiler::shared->compile_objc_stub(NULL, - node->ruby_imp, node->arity, types); + node->ruby_imp, node->arity, new_types); node->objc_imp = compile(objc_func); + // TODO: free LLVM machine code from old objc IMP objc_to_ruby_stubs[node->ruby_imp] = node->objc_imp; // Re-add the method. node = add_method(klass, node->sel, node->objc_imp, node->ruby_imp, - node->arity, node->flags, types); + node->arity, node->flags, new_types); return node; } Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2010-04-22 01:54:06 UTC (rev 3954) +++ MacRuby/trunk/vm.h 2010-04-22 04:22:47 UTC (rev 3955) @@ -796,7 +796,8 @@ Function *func, const rb_vm_arity_t &arity, int flags, IMP imp, Method m); rb_vm_method_node_t *retype_method(Class klass, - rb_vm_method_node_t *node, const char *types); + rb_vm_method_node_t *node, const char *old_types, + const char *new_types); void undef_method(Class klass, SEL sel); void remove_method(Class klass, SEL sel); bool resolve_methods(std::map<Class, rb_vm_method_source_t *> *map,
participants (1)
-
source_changes@macosforge.org