1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15: #include "ruby/ruby.h"
16: #include "ruby/st.h"
17: #include "ruby/util.h"
18: #include "debug.h"
19: #include <stdio.h>
20: #include <errno.h>
21: #include <ctype.h>
22: #include <math.h>
23:
24: VALUE rb_cBasicObject;
25: VALUE rb_mKernel;
26: VALUE rb_cObject;
27: VALUE rb_cModule;
28: VALUE rb_cClass;
29: VALUE rb_cData;
30:
31: VALUE rb_cNilClass;
32: VALUE rb_cTrueClass;
33: VALUE rb_cFalseClass;
34:
35: static ID id_eq, id_eql, id_match, id_inspect, id_init_copy;
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46: VALUE
47: rb_equal(VALUE obj1, VALUE obj2)
48: {
49: VALUE result;
50:
51: if (obj1 == obj2) return Qtrue;
52: result = rb_funcall(obj1, id_eq, 1, obj2);
53: if (RTEST(result)) return Qtrue;
54: return Qfalse;
55: }
56:
57: int
58: rb_eql(VALUE obj1, VALUE obj2)
59: {
60: return RTEST(rb_funcall(obj1, id_eql, 1, obj2));
61: }
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92: VALUE
93: rb_obj_equal(VALUE obj1, VALUE obj2)
94: {
95: if (obj1 == obj2) return Qtrue;
96: return Qfalse;
97: }
98:
99:
100:
101:
102:
103:
104:
105:
106: VALUE
107: rb_obj_not(VALUE obj)
108: {
109: return RTEST(obj) ? Qfalse : Qtrue;
110: }
111:
112:
113:
114:
115:
116:
117:
118:
119: VALUE
120: rb_obj_not_equal(VALUE obj1, VALUE obj2)
121: {
122: VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
123: return RTEST(result) ? Qfalse : Qtrue;
124: }
125:
126: VALUE
127: rb_class_real(VALUE cl)
128: {
129: if (cl == 0)
130: return 0;
131: while ((RBASIC(cl)->flags & FL_SINGLETON) || BUILTIN_TYPE(cl) == T_ICLASS) {
132: cl = RCLASS_SUPER(cl);
133: }
134: return cl;
135: }
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151: VALUE
152: rb_obj_class(VALUE obj)
153: {
154: return rb_class_real(CLASS_OF(obj));
155: }
156:
157: static void
158: init_copy(VALUE dest, VALUE obj)
159: {
160: if (OBJ_FROZEN(dest)) {
161: rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
162: }
163: RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
164: RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT);
165: rb_copy_generic_ivar(dest, obj);
166: rb_gc_copy_finalizer(dest, obj);
167: switch (TYPE(obj)) {
168: case T_OBJECT:
169: if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_PTR(dest)) {
170: xfree(ROBJECT_PTR(dest));
171: ROBJECT(dest)->as.heap.ptr = 0;
172: ROBJECT(dest)->as.heap.len = 0;
173: }
174: if (RBASIC(obj)->flags & ROBJECT_EMBED) {
175: MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
176: RBASIC(dest)->flags |= ROBJECT_EMBED;
177: }
178: else {
179: long len = ROBJECT(obj)->as.heap.len;
180: VALUE *ptr = ALLOC_N(VALUE, len);
181: MEMCPY(ptr, ROBJECT(obj)->as.heap.ptr, VALUE, len);
182: ROBJECT(dest)->as.heap.ptr = ptr;
183: ROBJECT(dest)->as.heap.len = len;
184: RBASIC(dest)->flags &= ~ROBJECT_EMBED;
185: }
186: break;
187: case T_CLASS:
188: case T_MODULE:
189: if (RCLASS_IV_TBL(dest)) {
190: st_free_table(RCLASS_IV_TBL(dest));
191: RCLASS_IV_TBL(dest) = 0;
192: }
193: if (RCLASS_IV_TBL(obj)) {
194: RCLASS_IV_TBL(dest) = st_copy(RCLASS_IV_TBL(obj));
195: }
196: break;
197: }
198: rb_funcall(dest, id_init_copy, 1, obj);
199: }
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225: VALUE
226: rb_obj_clone(VALUE obj)
227: {
228: VALUE clone;
229:
230: if (rb_special_const_p(obj)) {
231: rb_raise(rb_eTypeError, "can't clone %s", rb_obj_classname(obj));
232: }
233: clone = rb_obj_alloc(rb_obj_class(obj));
234: RBASIC(clone)->klass = rb_singleton_class_clone(obj);
235: RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE);
236: init_copy(clone, obj);
237: RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
238:
239: return clone;
240: }
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260: VALUE
261: rb_obj_dup(VALUE obj)
262: {
263: VALUE dup;
264:
265: if (rb_special_const_p(obj)) {
266: rb_raise(rb_eTypeError, "can't dup %s", rb_obj_classname(obj));
267: }
268: dup = rb_obj_alloc(rb_obj_class(obj));
269: init_copy(dup, obj);
270:
271: return dup;
272: }
273:
274:
275: VALUE
276: rb_obj_init_copy(VALUE obj, VALUE orig)
277: {
278: if (obj == orig) return obj;
279: rb_check_frozen(obj);
280: if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {
281: rb_raise(rb_eTypeError, "initialize_copy should take same class object");
282: }
283: return obj;
284: }
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296: VALUE
297: rb_any_to_s(VALUE obj)
298: {
299: char *cname = rb_obj_classname(obj);
300: VALUE str;
301:
302: str = rb_sprintf("#<%s:%p>", cname, (void*)obj);
303: if (OBJ_TAINTED(obj)) OBJ_TAINT(str);
304:
305: return str;
306: }
307:
308: VALUE
309: rb_inspect(VALUE obj)
310: {
311: return rb_obj_as_string(rb_funcall(obj, id_inspect, 0, 0));
312: }
313:
314: static int
315: inspect_i(ID id, VALUE value, VALUE str)
316: {
317: VALUE str2;
318: const char *ivname;
319:
320:
321: if (CLASS_OF(value) == 0) return ST_CONTINUE;
322: if (!rb_is_instance_id(id)) return ST_CONTINUE;
323: if (RSTRING_PTR(str)[0] == '-') {
324: RSTRING_PTR(str)[0] = '#';
325: rb_str_cat2(str, " ");
326: }
327: else {
328: rb_str_cat2(str, ", ");
329: }
330: ivname = rb_id2name(id);
331: rb_str_cat2(str, ivname);
332: rb_str_cat2(str, "=");
333: str2 = rb_inspect(value);
334: rb_str_append(str, str2);
335: OBJ_INFECT(str, str2);
336:
337: return ST_CONTINUE;
338: }
339:
340: static VALUE
341: inspect_obj(VALUE obj, VALUE str, int recur)
342: {
343: if (recur) {
344: rb_str_cat2(str, " ...");
345: }
346: else {
347: rb_ivar_foreach(obj, inspect_i, str);
348: }
349: rb_str_cat2(str, ">");
350: RSTRING_PTR(str)[0] = '#';
351: OBJ_INFECT(str, obj);
352:
353: return str;
354: }
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369: static VALUE
370: rb_obj_inspect(VALUE obj)
371: {
372:
373: if (TYPE(obj) == T_OBJECT) {
374: int has_ivar = 0;
375: VALUE *ptr = ROBJECT_PTR(obj);
376: long len = ROBJECT_LEN(obj);
377: long i;
378:
379: for (i = 0; i < len; i++) {
380: if (ptr[i] != Qundef) {
381: has_ivar = 1;
382: break;
383: }
384: }
385:
386: if (has_ivar) {
387: VALUE str;
388: char *c;
389:
390: c = rb_obj_classname(obj);
391: str = rb_sprintf("-<%s:%p", c, (void*)obj);
392: return rb_exec_recursive(inspect_obj, obj, str);
393: }
394: }
395: return rb_funcall(obj, rb_intern("to_s"), 0, 0);
396: }
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407: VALUE
408: rb_obj_is_instance_of(VALUE obj, VALUE c)
409: {
410: switch (TYPE(c)) {
411: case T_MODULE:
412: case T_CLASS:
413: case T_ICLASS:
414: break;
415: default:
416: rb_raise(rb_eTypeError, "class or module required");
417: }
418:
419: if (rb_obj_class(obj) == c) return Qtrue;
420: return Qfalse;
421: }
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450: VALUE
451: rb_obj_is_kind_of(VALUE obj, VALUE c)
452: {
453: VALUE cl = CLASS_OF(obj);
454:
455: switch (TYPE(c)) {
456: case T_MODULE:
457: case T_CLASS:
458: case T_ICLASS:
459: break;
460:
461: default:
462: rb_raise(rb_eTypeError, "class or module required");
463: }
464:
465: while (cl) {
466: if (cl == c || RCLASS_M_TBL(cl) == RCLASS_M_TBL(c))
467: return Qtrue;
468: cl = RCLASS_SUPER(cl);
469: }
470: return Qfalse;
471: }
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489: VALUE
490: rb_obj_tap(VALUE obj)
491: {
492: rb_yield(obj);
493: return obj;
494: }
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630: static VALUE
631: rb_obj_dummy(void)
632: {
633: return Qnil;
634: }
635:
636:
637:
638:
639:
640:
641:
642:
643: VALUE
644: rb_obj_tainted(VALUE obj)
645: {
646: if (OBJ_TAINTED(obj))
647: return Qtrue;
648: return Qfalse;
649: }
650:
651:
652:
653:
654:
655:
656:
657:
658:
659:
660: VALUE
661: rb_obj_taint(VALUE obj)
662: {
663: rb_secure(4);
664: if (!OBJ_TAINTED(obj)) {
665: if (OBJ_FROZEN(obj)) {
666: rb_error_frozen("object");
667: }
668: OBJ_TAINT(obj);
669: }
670: return obj;
671: }