Revision: 2694 http://trac.macosforge.org/projects/ruby/changeset/2694 Author: lsansonetti@apple.com Date: 2009-09-30 17:45:13 -0700 (Wed, 30 Sep 2009) Log Message: ----------- fixed variadic functions/methods calls Modified Paths: -------------- MacRuby/trunk/bridgesupport.cpp MacRuby/trunk/compiler.cpp MacRuby/trunk/compiler.h MacRuby/trunk/sprintf.cpp MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/bridgesupport.cpp =================================================================== --- MacRuby/trunk/bridgesupport.cpp 2009-09-30 23:43:09 UTC (rev 2693) +++ MacRuby/trunk/bridgesupport.cpp 2009-10-01 00:45:13 UTC (rev 2694) @@ -1300,8 +1300,8 @@ types.append(convert_ffi_type(RARRAY_AT(args, i), true)); } - rb_vm_c_stub_t *stub = (rb_vm_c_stub_t *)GET_CORE()->gen_stub(types, argc, - false); + rb_vm_c_stub_t *stub = (rb_vm_c_stub_t *)GET_CORE()->gen_stub(types, + false, argc, false); Function *f = RoxorCompiler::shared->compile_ffi_function((void *)stub, sym, argc); IMP imp = GET_CORE()->compile(f); Modified: MacRuby/trunk/compiler.cpp =================================================================== --- MacRuby/trunk/compiler.cpp 2009-09-30 23:43:09 UTC (rev 2693) +++ MacRuby/trunk/compiler.cpp 2009-10-01 00:45:13 UTC (rev 2694) @@ -6505,7 +6505,8 @@ } Function * -RoxorCompiler::compile_stub(const char *types, int argc, bool is_objc) +RoxorCompiler::compile_stub(const char *types, bool variadic, int min_argc, + bool is_objc) { Function *f; @@ -6575,10 +6576,10 @@ // Arguments. std::vector<unsigned int> byval_args; int given_argc = 0; - bool variadic = false; + bool stop_arg_type = false; while ((p = GetFirstType(p, buf, sizeof buf)) != NULL && buf[0] != '\0') { - if (given_argc == argc) { - variadic = true; + if (variadic && given_argc == min_argc) { + stop_arg_type = true; } const Type *llvm_type = convert_type(buf); @@ -6592,7 +6593,7 @@ byval_args.push_back(f_types.size() + 1 /* retval */); } - if (!variadic) { + if (!stop_arg_type) { // In order to conform to the ABI, we must stop providing types // once we start dealing with variable arguments and instead mark // the function as variadic. Modified: MacRuby/trunk/compiler.h =================================================================== --- MacRuby/trunk/compiler.h 2009-09-30 23:43:09 UTC (rev 2693) +++ MacRuby/trunk/compiler.h 2009-10-01 00:45:13 UTC (rev 2694) @@ -52,7 +52,8 @@ virtual Function *compile_main_function(NODE *node); Function *compile_read_attr(ID name); Function *compile_write_attr(ID name); - Function *compile_stub(const char *types, int argc, bool is_objc); + Function *compile_stub(const char *types, bool variadic, int min_argc, + bool is_objc); Function *compile_bs_struct_new(rb_vm_bs_boxed_t *bs_boxed); Function *compile_bs_struct_writer(rb_vm_bs_boxed_t *bs_boxed, int field); Modified: MacRuby/trunk/sprintf.cpp =================================================================== --- MacRuby/trunk/sprintf.cpp 2009-09-30 23:43:09 UTC (rev 2693) +++ MacRuby/trunk/sprintf.cpp 2009-10-01 00:45:13 UTC (rev 2694) @@ -491,7 +491,7 @@ } rb_vm_c_stub_t *stub = (rb_vm_c_stub_t *)GET_CORE()->gen_stub(types, - 3, false); + true, 3, false); VALUE str = (*stub)((IMP)&CFStringCreateWithFormat, argc + 3, stub_args); CFMakeCollectable((void *)str); Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2009-09-30 23:43:09 UTC (rev 2693) +++ MacRuby/trunk/vm.cpp 2009-10-01 00:45:13 UTC (rev 2694) @@ -2513,16 +2513,22 @@ } void * -RoxorCore::gen_stub(std::string types, int argc, bool is_objc) +RoxorCore::gen_stub(std::string types, bool variadic, int min_argc, + bool is_objc) { lock(); +#if ROXOR_VM_DEBUG + printf("gen Ruby -> %s stub with types %s\n", is_objc ? "ObjC" : "C", + types.c_str()); +#endif + std::map<std::string, void *> &stubs = is_objc ? objc_stubs : c_stubs; std::map<std::string, void *>::iterator iter = stubs.find(types); void *stub; if (iter == stubs.end()) { - Function *f = RoxorCompiler::shared->compile_stub(types.c_str(), argc, - is_objc); + Function *f = RoxorCompiler::shared->compile_stub(types.c_str(), + variadic, min_argc, is_objc); stub = (void *)compile(f); stubs.insert(std::make_pair(types, stub)); } @@ -2570,12 +2576,25 @@ } static inline void -vm_gen_bs_func_types(bs_element_function_t *bs_func, std::string &types) +vm_gen_bs_func_types(int argc, const VALUE *argv, + bs_element_function_t *bs_func, std::string &types) { types.append(bs_func->retval == NULL ? "v" : bs_func->retval->type); - for (unsigned i = 0; i < bs_func->args_count; i++) { + int printf_arg = -1; + for (int i = 0; i < (int)bs_func->args_count; i++) { types.append(bs_func->args[i].type); + if (bs_func->args[i].printf_format) { + printf_arg = i; + } } + if (bs_func->variadic) { + // TODO honor printf_format +// if (printf_arg != -1) { +// } + for (int i = bs_func->args_count; i < argc; i++) { + types.append("@"); + } + } } static inline SEL @@ -2692,8 +2711,10 @@ sel_getName(sel)); abort(); } + bool variadic = false; if (ocache.bs_method != NULL && ocache.bs_method->variadic && method != NULL) { + // TODO honor printf_format const int real_argc = method_getNumberOfArguments(method) - 2; if (real_argc < argc) { const size_t s = strlen(types); @@ -2703,8 +2724,9 @@ } argc = real_argc; } + variadic = true; } - ocache.stub = (rb_vm_objc_stub_t *)GET_CORE()->gen_stub(types, + ocache.stub = (rb_vm_objc_stub_t *)GET_CORE()->gen_stub(types, variadic, argc, true); } @@ -2835,14 +2857,14 @@ bs_element_function_t *bs_func = GET_CORE()->find_bs_function(name); if (bs_func != NULL) { std::string types; - vm_gen_bs_func_types(bs_func, types); + vm_gen_bs_func_types(argc, argv, bs_func, types); cache->flag = MCACHE_FCALL; fcache.bs_function = bs_func; fcache.imp = (IMP)dlsym(RTLD_DEFAULT, bs_func->name); assert(fcache.imp != NULL); fcache.stub = (rb_vm_c_stub_t *)GET_CORE()->gen_stub(types, - argc, false); + bs_func->variadic, bs_func->args_count, false); } else { // Still nothing, then let's call #method_missing. Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2009-09-30 23:43:09 UTC (rev 2693) +++ MacRuby/trunk/vm.h 2009-10-01 00:45:13 UTC (rev 2694) @@ -638,7 +638,8 @@ // This callback is public for the only reason it's called by C. void bs_parse_cb(bs_element_type_t type, void *value, void *ctx); - void *gen_stub(std::string types, int argc, bool is_objc); + void *gen_stub(std::string types, bool variadic, int min_argc, + bool is_objc); void *gen_to_rval_convertor(std::string type); void *gen_to_ocval_convertor(std::string type);
participants (1)
-
source_changes@macosforge.org