Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 853 lines (767 sloc) 21.079 kB
9c1d230 committing experimental branch content
Laurent Sansonetti authored
1 /* -*-c-*- */
2 /*
3 * This file is included by vm_eval.c
4 */
5
6 static ID __send__, object_id;
7 static ID removed, singleton_removed, undefined, singleton_undefined;
8 static ID eqq, each, aref, aset, match, missing;
9 static ID added, singleton_added;
10
11 void
12 rb_add_method(VALUE klass, ID mid, NODE * node, int noex)
13 {
14 // TODO
15 return;
16 }
17
18 void
19 rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE))
20 {
21 // TODO
22 #if 0
23 Check_Type(klass, T_CLASS);
24 rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0),
25 NOEX_PUBLIC);
26 #endif
27 }
28
29 void
30 rb_undef_alloc_func(VALUE klass)
31 {
32 // TODO
33 #if 0
34 Check_Type(klass, T_CLASS);
35 rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
36 #endif
37 }
38
39 rb_alloc_func_t
40 rb_get_alloc_func(VALUE klass)
41 {
42 NODE *n;
43 Check_Type(klass, T_CLASS);
44 n = rb_method_node(CLASS_OF(klass), ID_ALLOCATOR);
45 if (!n) return 0;
46 if (nd_type(n) != NODE_METHOD) return 0;
47 n = n->nd_body;
48 if (nd_type(n) != NODE_CFUNC) return 0;
49 return (rb_alloc_func_t)n->nd_cfnc;
50 }
51
52 static NODE *
53 search_method(VALUE klass, ID id, VALUE *klassp)
54 {
55 NODE *node;
56 if (klass == 0) {
57 return NULL;
58 }
59 node = rb_method_node(klass, id);
60 if (node != NULL) {
61 if (klassp != NULL) { /* TODO honour klassp */
62 *klassp = klass;
63 }
64 }
65 return node;
66 }
67
68 /*
69 * search method body (NODE_METHOD)
70 * with : klass and id
71 * without : method cache
72 *
73 * if you need method node with method cache, use
74 * rb_method_node()
75 */
76 NODE *
77 rb_get_method_body(VALUE klass, ID id, ID *idp)
78 {
79 return search_method(klass, id, NULL);
80 }
81
82 NODE *
83 rb_method_node(VALUE klass, ID id)
84 {
3c2c617 disable rb_method_node() for now because it's wrongly implemented
Laurent Sansonetti authored
85 return NULL;
86 #if 0 // TODO
9c1d230 committing experimental branch content
Laurent Sansonetti authored
87 NODE *node = rb_objc_method_node(klass, id, NULL, NULL);
88 if (node == NULL && id != ID_ALLOCATOR) {
89 const char *id_str = rb_id2name(id);
90 size_t slen = strlen(id_str);
91
92 if (strcmp(id_str, "retain") == 0
93 || strcmp(id_str, "release") == 0
94 || strcmp(id_str, "zone") == 0) {
95 char buf[100];
96 snprintf(buf, sizeof buf, "__rb_%s__", id_str);
97 return rb_method_node(klass, rb_intern(buf));
98 }
99 else {
100 if (id_str[slen - 1] == ':') {
101 return NULL;
102 }
103 else {
104 char buf[100];
105 snprintf(buf, sizeof buf, "%s:", id_str);
106 return rb_method_node(klass, rb_intern(buf));
107 }
108 }
109 }
110 return node;
3c2c617 disable rb_method_node() for now because it's wrongly implemented
Laurent Sansonetti authored
111 #endif
9c1d230 committing experimental branch content
Laurent Sansonetti authored
112 }
113
114 static void
115 remove_method(VALUE klass, ID mid)
116 {
117 if (klass == rb_cObject) {
118 rb_secure(4);
119 }
120 if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
121 rb_raise(rb_eSecurityError, "Insecure: can't remove method");
122 }
123 if (OBJ_FROZEN(klass))
124 rb_error_frozen("class/module");
125 if (mid == object_id || mid == __send__ || mid == idInitialize) {
126 rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
127 }
128 SEL sel;
129 Method m;
130
131 sel = sel_registerName(rb_id2name(mid));
132 m = class_getInstanceMethod((Class)klass, sel);
133 if (m == NULL) {
134 char buf[100];
135 size_t len = strlen((char *)sel);
136 if (((char *)sel)[len - 1] != ':') {
137 snprintf(buf, sizeof buf, "%s:", (char *)sel);
138 sel = sel_registerName(buf);
139 m = class_getInstanceMethod((Class)klass, sel);
140 }
141 }
142 if (m == NULL) {
143 rb_name_error(mid, "method `%s' not defined in %s",
144 rb_id2name(mid), rb_class2name(klass));
145 }
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
146 if (!rb_vm_is_ruby_method(m)) {
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
147 rb_warn("removing pure Objective-C method `%s' may cause serious " \
148 "problem", rb_id2name(mid));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
149 }
150 method_setImplementation(m, NULL);
151
152 if (RCLASS_SINGLETON(klass)) {
153 rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1,
154 ID2SYM(mid));
155 }
156 else {
157 rb_funcall(klass, removed, 1, ID2SYM(mid));
158 }
159 }
160
161 void
162 rb_remove_method(VALUE klass, const char *name)
163 {
164 remove_method(klass, rb_intern(name));
165 }
166
167 /*
168 * call-seq:
169 * remove_method(symbol) => self
170 *
171 * Removes the method identified by _symbol_ from the current
172 * class. For an example, see <code>Module.undef_method</code>.
173 */
174
175 static VALUE
176 rb_mod_remove_method(VALUE mod, SEL sel, int argc, VALUE *argv)
177 {
178 int i;
179
180 for (i = 0; i < argc; i++) {
181 remove_method(mod, rb_to_id(argv[i]));
182 }
183 return mod;
184 }
185
186 #undef rb_disable_super
187 #undef rb_enable_super
188
189 void
190 rb_disable_super(VALUE klass, const char *name)
191 {
192 /* obsolete - no use */
193 }
194
195 void
196 rb_enable_super(VALUE klass, const char *name)
197 {
198 rb_warning("rb_enable_super() is obsolete");
199 }
200
201 void rb_print_undef(VALUE, ID, int);
202
203 static void
204 rb_export_method(VALUE klass, ID name, ID noex)
205 {
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
206 rb_vm_method_node_t *node;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
207 SEL sel;
208
209 if (klass == rb_cObject) {
210 rb_secure(4);
211 }
212
213 if (!rb_vm_lookup_method2((Class)klass, name, &sel, NULL, &node)) {
214 if (TYPE(klass) != T_MODULE
215 || !rb_vm_lookup_method2((Class)rb_cObject, name, &sel, NULL, &node)) {
216 rb_print_undef(klass, name, 0);
217 }
218 }
219
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
220 if (node == NULL) {
221 rb_raise(rb_eRuntimeError,
222 "can't change visibility of non Ruby method `%s'",
223 sel_getName(sel));
224 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
225
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
226 VALUE sklass = RCLASS_SUPER(klass);
227 if (sklass != 0) {
228 Method m = class_getInstanceMethod((Class)sklass, sel);
229 if (m != NULL && method_getImplementation(m) == node->objc_imp) {
230 // The method actually exists on a superclass, we need to duplicate
231 // it to the current class then change its visibility.
232 node = rb_vm_define_method2((Class)klass, sel, node, false);
233 }
234 }
235
236 switch (noex) {
237 case NOEX_PUBLIC:
238 node->flags |= 0;
239 break;
240
241 case NOEX_PRIVATE:
242 node->flags |= VM_METHOD_PRIVATE;
243 break;
244
245 case NOEX_PROTECTED:
246 node->flags |= VM_METHOD_PROTECTED;
247 break;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
248 }
249 }
250
251 int
252 rb_method_boundp(VALUE klass, ID id, int ex)
253 {
254 NODE *method;
255
256 if ((method = rb_method_node(klass, id)) != 0) {
257 if (ex && (method->nd_noex & NOEX_PRIVATE)) {
258 return Qfalse;
259 }
260 return Qtrue;
261 }
262 return Qfalse;
263 }
264
265 void
266 rb_attr(VALUE klass, ID id, int read, int write, int ex)
267 {
268 if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
269 rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
270 }
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
271 const char *name = rb_id2name(id);
272 if (name == NULL) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
273 rb_raise(rb_eArgError, "argument needs to be symbol or string");
274 }
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
275 rb_vm_define_attr((Class)klass, name, read, write);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
276 if (write) {
277 rb_objc_define_kvo_setter(klass, id);
278 }
279 }
280
281 void
282 rb_undef(VALUE klass, ID id)
283 {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
284 if (klass == rb_cObject) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
285 rb_secure(4);
286 }
287 if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
288 rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
289 rb_id2name(id));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
290 }
291 rb_frozen_class_p(klass);
292 if (id == object_id || id == __send__ || id == idInitialize) {
293 rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
294 }
295
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
296 rb_vm_undef_method((Class)klass, id, true);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
297 }
298
299 /*
300 * call-seq:
301 * undef_method(symbol) => self
302 *
303 * Prevents the current class from responding to calls to the named
304 * method. Contrast this with <code>remove_method</code>, which deletes
305 * the method from the particular class; Ruby will still search
306 * superclasses and mixed-in modules for a possible receiver.
307 *
308 * class Parent
309 * def hello
310 * puts "In parent"
311 * end
312 * end
313 * class Child < Parent
314 * def hello
315 * puts "In child"
316 * end
317 * end
318 *
319 *
320 * c = Child.new
321 * c.hello
322 *
323 *
324 * class Child
325 * remove_method :hello # remove from child, still in parent
326 * end
327 * c.hello
328 *
329 *
330 * class Child
331 * undef_method :hello # prevent any calls to 'hello'
332 * end
333 * c.hello
334 *
335 * <em>produces:</em>
336 *
337 * In child
338 * In parent
339 * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
340 */
341
342 static VALUE
343 rb_mod_undef_method(VALUE mod, SEL sel, int argc, VALUE *argv)
344 {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
345 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
346 rb_undef(mod, rb_to_id(argv[i]));
347 }
348 return mod;
349 }
350
351 /*
352 * call-seq:
353 * mod.method_defined?(symbol) => true or false
354 *
355 * Returns +true+ if the named method is defined by
356 * _mod_ (or its included modules and, if _mod_ is a class,
357 * its ancestors). Public and protected methods are matched.
358 *
359 * module A
360 * def method1() end
361 * end
362 * class B
363 * def method2() end
364 * end
365 * class C < B
366 * include A
367 * def method3() end
368 * end
369 *
370 * A.method_defined? :method1 #=> true
371 * C.method_defined? "method1" #=> true
372 * C.method_defined? "method2" #=> true
373 * C.method_defined? "method3" #=> true
374 * C.method_defined? "method4" #=> false
375 */
376
377 static VALUE
378 rb_mod_method_defined(VALUE mod, SEL sel, VALUE mid)
379 {
914ab2b fixed Module#method_defined?
Laurent Sansonetti authored
380 ID id = rb_to_id(mid);
381 return rb_obj_respond_to(mod, id, true) ? Qtrue : Qfalse;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
382 }
383
384 #define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
385
386 /*
387 * call-seq:
388 * mod.public_method_defined?(symbol) => true or false
389 *
390 * Returns +true+ if the named public method is defined by
391 * _mod_ (or its included modules and, if _mod_ is a class,
392 * its ancestors).
393 *
394 * module A
395 * def method1() end
396 * end
397 * class B
398 * protected
399 * def method2() end
400 * end
401 * class C < B
402 * include A
403 * def method3() end
404 * end
405 *
406 * A.method_defined? :method1 #=> true
407 * C.public_method_defined? "method1" #=> true
408 * C.public_method_defined? "method2" #=> false
409 * C.method_defined? "method2" #=> true
410 */
411
412 static VALUE
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
413 check_method_visibility(VALUE mod, ID id, int visi)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
414 {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
415 rb_vm_method_node_t *node;
416 if (rb_vm_lookup_method2((Class)mod, id, NULL, NULL, &node)) {
417 if (node != NULL) {
418 if (node->flags & rb_vm_noex_flag(visi)) {
419 return Qtrue;
420 }
421 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
422 }
423 return Qfalse;
424 }
425
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
426 static VALUE
427 rb_mod_public_method_defined(VALUE mod, SEL sel, VALUE mid)
428 {
429 ID id = rb_to_id(mid);
430 return check_method_visibility(mod, id, NOEX_PUBLIC);
431 }
432
9c1d230 committing experimental branch content
Laurent Sansonetti authored
433 /*
434 * call-seq:
435 * mod.private_method_defined?(symbol) => true or false
436 *
437 * Returns +true+ if the named private method is defined by
438 * _ mod_ (or its included modules and, if _mod_ is a class,
439 * its ancestors).
440 *
441 * module A
442 * def method1() end
443 * end
444 * class B
445 * private
446 * def method2() end
447 * end
448 * class C < B
449 * include A
450 * def method3() end
451 * end
452 *
453 * A.method_defined? :method1 #=> true
454 * C.private_method_defined? "method1" #=> false
455 * C.private_method_defined? "method2" #=> true
456 * C.method_defined? "method2" #=> false
457 */
458
459 static VALUE
460 rb_mod_private_method_defined(VALUE mod, SEL sel, VALUE mid)
461 {
462 ID id = rb_to_id(mid);
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
463 return check_method_visibility(mod, id, NOEX_PRIVATE);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
464 }
465
466 /*
467 * call-seq:
468 * mod.protected_method_defined?(symbol) => true or false
469 *
470 * Returns +true+ if the named protected method is defined
471 * by _mod_ (or its included modules and, if _mod_ is a
472 * class, its ancestors).
473 *
474 * module A
475 * def method1() end
476 * end
477 * class B
478 * protected
479 * def method2() end
480 * end
481 * class C < B
482 * include A
483 * def method3() end
484 * end
485 *
486 * A.method_defined? :method1 #=> true
487 * C.protected_method_defined? "method1" #=> false
488 * C.protected_method_defined? "method2" #=> true
489 * C.method_defined? "method2" #=> true
490 */
491
492 static VALUE
493 rb_mod_protected_method_defined(VALUE mod, SEL sel, VALUE mid)
494 {
495 ID id = rb_to_id(mid);
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
496 return check_method_visibility(mod, id, NOEX_PROTECTED);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
497 }
498
499 void
500 rb_alias(VALUE klass, ID name, ID def)
501 {
502 rb_vm_alias(klass, name, def);
503 }
504
505 /*
506 * call-seq:
507 * alias_method(new_name, old_name) => self
508 *
509 * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
510 * be used to retain access to methods that are overridden.
511 *
512 * module Mod
513 * alias_method :orig_exit, :exit
514 * def exit(code=0)
515 * puts "Exiting with code #{code}"
516 * orig_exit(code)
517 * end
518 * end
519 * include Mod
520 * exit(99)
521 *
522 * <em>produces:</em>
523 *
524 * Exiting with code 99
525 */
526
527 static VALUE
528 rb_mod_alias_method(VALUE mod, SEL sel, VALUE newname, VALUE oldname)
529 {
530 rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
531 return mod;
532 }
533
534 static void
535 secure_visibility(VALUE self)
536 {
537 if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
538 rb_raise(rb_eSecurityError,
539 "Insecure: can't change method visibility");
540 }
541 }
542
543 static void
544 set_method_visibility(VALUE self, int argc, VALUE *argv, ID ex)
545 {
546 secure_visibility(self);
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
547 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
548 rb_export_method(self, rb_to_id(argv[i]), ex);
549 }
550 }
551
552 /*
553 * call-seq:
554 * public => self
555 * public(symbol, ...) => self
556 *
557 * With no arguments, sets the default visibility for subsequently
558 * defined methods to public. With arguments, sets the named methods to
559 * have public visibility.
560 */
561
562 static VALUE
563 rb_mod_public(VALUE module, SEL sel, int argc, VALUE *argv)
564 {
565 secure_visibility(module);
566 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
567 rb_vm_set_current_scope(module, SCOPE_PUBLIC);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
568 }
569 else {
570 set_method_visibility(module, argc, argv, NOEX_PUBLIC);
571 }
572 return module;
573 }
574
575 /*
576 * call-seq:
577 * protected => self
578 * protected(symbol, ...) => self
579 *
580 * With no arguments, sets the default visibility for subsequently
581 * defined methods to protected. With arguments, sets the named methods
582 * to have protected visibility.
583 */
584
585 static VALUE
586 rb_mod_protected(VALUE module, SEL sel, int argc, VALUE *argv)
587 {
588 secure_visibility(module);
589 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
590 rb_vm_set_current_scope(module, SCOPE_PROTECTED);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
591 }
592 else {
593 set_method_visibility(module, argc, argv, NOEX_PROTECTED);
594 }
595 return module;
596 }
597
598 /*
599 * call-seq:
600 * private => self
601 * private(symbol, ...) => self
602 *
603 * With no arguments, sets the default visibility for subsequently
604 * defined methods to private. With arguments, sets the named methods
605 * to have private visibility.
606 *
607 * module Mod
608 * def a() end
609 * def b() end
610 * private
611 * def c() end
612 * private :a
613 * end
614 * Mod.private_instance_methods #=> [:a, :c]
615 */
616
617 static VALUE
618 rb_mod_private(VALUE module, SEL sel, int argc, VALUE *argv)
619 {
620 secure_visibility(module);
621 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
622 rb_vm_set_current_scope(module, SCOPE_PRIVATE);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
623 }
624 else {
625 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
626 }
627 return module;
628 }
629
630 /*
631 * call-seq:
632 * mod.public_class_method(symbol, ...) => mod
633 *
634 * Makes a list of existing class methods public.
635 */
636
637 static VALUE
638 rb_mod_public_method(VALUE obj, SEL sel, int argc, VALUE *argv)
639 {
640 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);
641 return obj;
642 }
643
644 /*
645 * call-seq:
646 * mod.private_class_method(symbol, ...) => mod
647 *
648 * Makes existing class methods private. Often used to hide the default
649 * constructor <code>new</code>.
650 *
651 * class SimpleSingleton # Not thread safe
652 * private_class_method :new
653 * def SimpleSingleton.create(*args, &block)
654 * @me = new(*args, &block) if ! @me
655 * @me
656 * end
657 * end
658 */
659
660 static VALUE
661 rb_mod_private_method(VALUE obj, SEL sel, int argc, VALUE *argv)
662 {
663 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);
664 return obj;
665 }
666
667 /*
668 * call-seq:
669 * public
670 * public(symbol, ...)
671 *
672 * With no arguments, sets the default visibility for subsequently
673 * defined methods to public. With arguments, sets the named methods to
674 * have public visibility.
675 */
676
677 static VALUE
678 top_public(VALUE recv, SEL sel, int argc, VALUE *argv)
679 {
680 return rb_mod_public(rb_cObject, 0, argc, argv);
681 }
682
683 static VALUE
684 top_private(VALUE recv, SEL sel, int argc, VALUE *argv)
685 {
686 return rb_mod_private(rb_cObject, 0, argc, argv);
687 }
688
689 /*
690 * call-seq:
691 * module_function(symbol, ...) => self
692 *
693 * Creates module functions for the named methods. These functions may
694 * be called with the module as a receiver, and also become available
695 * as instance methods to classes that mix in the module. Module
696 * functions are copies of the original, and so may be changed
697 * independently. The instance-method versions are made private. If
698 * used with no arguments, subsequently defined methods become module
699 * functions.
700 *
701 * module Mod
702 * def one
703 * "This is one"
704 * end
705 * module_function :one
706 * end
707 * class Cls
708 * include Mod
709 * def callOne
710 * one
711 * end
712 * end
713 * Mod.one #=> "This is one"
714 * c = Cls.new
715 * c.callOne #=> "This is one"
716 * module Mod
717 * def one
718 * "This is the new one"
719 * end
720 * end
721 * Mod.one #=> "This is one"
722 * c.callOne #=> "This is the new one"
723 */
724
725 static VALUE
726 rb_mod_modfunc(VALUE module, SEL sel, int argc, VALUE *argv)
727 {
728 if (TYPE(module) != T_MODULE) {
729 rb_raise(rb_eTypeError, "module_function must be called for modules");
730 }
731
732 secure_visibility(module);
733 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
734 rb_vm_set_current_scope(module, SCOPE_MODULE_FUNC);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
735 return module;
736 }
737
738 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
739
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
740 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
741 ID id = rb_to_id(argv[i]);
742 IMP imp;
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
743 rb_vm_method_node_t *node;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
744 SEL sel;
745
746 if (!rb_vm_lookup_method2((Class)module, id, &sel, &imp, &node)) {
747 // Methods are checked in set_method_visibility().
748 rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
749 }
750
a6e43f0 fix a few regressions
Laurent Sansonetti authored
751 rb_vm_define_method2(*(Class *)module, sel, node, false);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
752 }
753
754 return module;
755 }
756
757 /*
758 * call-seq:
759 * obj.respond_to?(symbol, include_private=false) => true or false
760 *
761 * Returns +true+> if _obj_ responds to the given
762 * method. Private methods are included in the search only if the
763 * optional second parameter evaluates to +true+.
764 */
765
766 //static NODE *basic_respond_to = 0;
767
914ab2b fixed Module#method_defined?
Laurent Sansonetti authored
768 bool
769 rb_obj_respond_to(VALUE obj, ID id, bool priv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
770 {
771 const char *id_name = rb_id2name(id);
772 SEL sel = sel_registerName(id_name);
773 if (!rb_vm_respond_to(obj, sel, priv)) {
774 char buf[100];
775 snprintf(buf, sizeof buf, "%s:", id_name);
776 sel = sel_registerName(buf);
914ab2b fixed Module#method_defined?
Laurent Sansonetti authored
777 return rb_vm_respond_to(obj, sel, priv);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
778 }
914ab2b fixed Module#method_defined?
Laurent Sansonetti authored
779 return true;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
780 }
781
914ab2b fixed Module#method_defined?
Laurent Sansonetti authored
782 bool
9c1d230 committing experimental branch content
Laurent Sansonetti authored
783 rb_respond_to(VALUE obj, ID id)
784 {
785 return rb_obj_respond_to(obj, id, Qfalse);
786 }
787
788 /*
789 * call-seq:
790 * obj.respond_to?(symbol, include_private=false) => true or false
791 *
792 * Returns +true+> if _obj_ responds to the given
793 * method. Private methods are included in the search only if the
794 * optional second parameter evaluates to +true+.
795 */
796
797 static VALUE
798 obj_respond_to(VALUE obj, SEL sel, int argc, VALUE *argv)
799 {
800 VALUE mid, priv;
801 ID id;
802
803 rb_scan_args(argc, argv, "11", &mid, &priv);
804 id = rb_to_id(mid);
805 return rb_obj_respond_to(obj, id, RTEST(priv)) ? Qtrue : Qfalse;
806 }
807
808 IMP basic_respond_to_imp = NULL;
809
810 void
811 Init_eval_method(void)
812 {
813 rb_objc_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
814 basic_respond_to_imp = class_getMethodImplementation((Class)rb_mKernel, selRespondTo);
815 //basic_respond_to = rb_method_node(rb_cObject, idRespond_to);
816 //rb_register_mark_object((VALUE)basic_respond_to);
817
818 rb_objc_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
819 rb_objc_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
820 rb_objc_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
821 rb_objc_define_private_method(rb_cModule, "public", rb_mod_public, -1);
822 rb_objc_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
823 rb_objc_define_private_method(rb_cModule, "private", rb_mod_private, -1);
824 rb_objc_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
825
826 rb_objc_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
827 rb_objc_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
828 rb_objc_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
829 rb_objc_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
830 rb_objc_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
831 rb_objc_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
832
833 VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
834 rb_objc_define_method(cTopLevel, "public", top_public, -1);
835 rb_objc_define_method(cTopLevel, "private", top_private, -1);
836
837 object_id = rb_intern("object_id");
838 __send__ = rb_intern("__send__");
839 eqq = rb_intern("===");
840 each = rb_intern("each");
841 aref = rb_intern("[]");
842 aset = rb_intern("[]=");
843 match = rb_intern("=~");
844 missing = rb_intern("method_missing");
845 added = rb_intern("method_added");
846 singleton_added = rb_intern("singleton_method_added");
847 removed = rb_intern("method_removed");
848 singleton_removed = rb_intern("singleton_method_removed");
849 undefined = rb_intern("method_undefined");
850 singleton_undefined = rb_intern("singleton_method_undefined");
851 }
852
Something went wrong with that request. Please try again.