Skip to content

HTTPS clone URL

Subversion checkout URL

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