00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "eval_intern.h"
00013 #include "gc.h"
00014
00015 struct METHOD {
00016 VALUE recv;
00017 VALUE rclass;
00018 ID id;
00019 rb_method_entry_t me;
00020 };
00021
00022 VALUE rb_cUnboundMethod;
00023 VALUE rb_cMethod;
00024 VALUE rb_cBinding;
00025 VALUE rb_cProc;
00026
00027 VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
00028
00029 static VALUE bmcall(VALUE, VALUE);
00030 static int method_arity(VALUE);
00031 static int rb_obj_is_method(VALUE m);
00032 rb_iseq_t *rb_method_get_iseq(VALUE method);
00033
00034
00035
00036 #define IS_METHOD_PROC_NODE(node) (nd_type(node) == NODE_IFUNC && (node)->nd_cfnc == bmcall)
00037
00038 static void
00039 proc_free(void *ptr)
00040 {
00041 RUBY_FREE_ENTER("proc");
00042 if (ptr) {
00043 ruby_xfree(ptr);
00044 }
00045 RUBY_FREE_LEAVE("proc");
00046 }
00047
00048 static void
00049 proc_mark(void *ptr)
00050 {
00051 rb_proc_t *proc;
00052 RUBY_MARK_ENTER("proc");
00053 if (ptr) {
00054 proc = ptr;
00055 RUBY_MARK_UNLESS_NULL(proc->envval);
00056 RUBY_MARK_UNLESS_NULL(proc->blockprocval);
00057 RUBY_MARK_UNLESS_NULL(proc->block.proc);
00058 RUBY_MARK_UNLESS_NULL(proc->block.self);
00059 if (proc->block.iseq && RUBY_VM_IFUNC_P(proc->block.iseq)) {
00060 RUBY_MARK_UNLESS_NULL((VALUE)(proc->block.iseq));
00061 }
00062 }
00063 RUBY_MARK_LEAVE("proc");
00064 }
00065
00066 static size_t
00067 proc_memsize(const void *ptr)
00068 {
00069 return ptr ? sizeof(rb_proc_t) : 0;
00070 }
00071
00072 static const rb_data_type_t proc_data_type = {
00073 "proc",
00074 proc_mark,
00075 proc_free,
00076 proc_memsize,
00077 };
00078
00079 VALUE
00080 rb_proc_alloc(VALUE klass)
00081 {
00082 rb_proc_t *proc;
00083 return TypedData_Make_Struct(klass, rb_proc_t, &proc_data_type, proc);
00084 }
00085
00086 VALUE
00087 rb_obj_is_proc(VALUE proc)
00088 {
00089 if (rb_typeddata_is_kind_of(proc, &proc_data_type)) {
00090 return Qtrue;
00091 }
00092 else {
00093 return Qfalse;
00094 }
00095 }
00096
00097
00098 static VALUE
00099 proc_dup(VALUE self)
00100 {
00101 VALUE procval = rb_proc_alloc(rb_cProc);
00102 rb_proc_t *src, *dst;
00103 GetProcPtr(self, src);
00104 GetProcPtr(procval, dst);
00105
00106 dst->block = src->block;
00107 dst->block.proc = procval;
00108 dst->blockprocval = src->blockprocval;
00109 dst->envval = src->envval;
00110 dst->safe_level = src->safe_level;
00111 dst->is_lambda = src->is_lambda;
00112
00113 return procval;
00114 }
00115
00116
00117 static VALUE
00118 proc_clone(VALUE self)
00119 {
00120 VALUE procval = proc_dup(self);
00121 CLONESETUP(procval, self);
00122 return procval;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 VALUE
00228 rb_proc_lambda_p(VALUE procval)
00229 {
00230 rb_proc_t *proc;
00231 GetProcPtr(procval, proc);
00232
00233 return proc->is_lambda ? Qtrue : Qfalse;
00234 }
00235
00236
00237
00238 static void
00239 binding_free(void *ptr)
00240 {
00241 rb_binding_t *bind;
00242 RUBY_FREE_ENTER("binding");
00243 if (ptr) {
00244 bind = ptr;
00245 ruby_xfree(ptr);
00246 }
00247 RUBY_FREE_LEAVE("binding");
00248 }
00249
00250 static void
00251 binding_mark(void *ptr)
00252 {
00253 rb_binding_t *bind;
00254 RUBY_MARK_ENTER("binding");
00255 if (ptr) {
00256 bind = ptr;
00257 RUBY_MARK_UNLESS_NULL(bind->env);
00258 RUBY_MARK_UNLESS_NULL(bind->filename);
00259 }
00260 RUBY_MARK_LEAVE("binding");
00261 }
00262
00263 static size_t
00264 binding_memsize(const void *ptr)
00265 {
00266 return ptr ? sizeof(rb_binding_t) : 0;
00267 }
00268
00269 static const rb_data_type_t binding_data_type = {
00270 "binding",
00271 binding_mark,
00272 binding_free,
00273 binding_memsize,
00274 };
00275
00276 static VALUE
00277 binding_alloc(VALUE klass)
00278 {
00279 VALUE obj;
00280 rb_binding_t *bind;
00281 obj = TypedData_Make_Struct(klass, rb_binding_t, &binding_data_type, bind);
00282 return obj;
00283 }
00284
00285
00286 static VALUE
00287 binding_dup(VALUE self)
00288 {
00289 VALUE bindval = binding_alloc(rb_cBinding);
00290 rb_binding_t *src, *dst;
00291 GetBindingPtr(self, src);
00292 GetBindingPtr(bindval, dst);
00293 dst->env = src->env;
00294 dst->filename = src->filename;
00295 dst->line_no = src->line_no;
00296 return bindval;
00297 }
00298
00299
00300 static VALUE
00301 binding_clone(VALUE self)
00302 {
00303 VALUE bindval = binding_dup(self);
00304 CLONESETUP(bindval, self);
00305 return bindval;
00306 }
00307
00308 VALUE
00309 rb_binding_new(void)
00310 {
00311 rb_thread_t *th = GET_THREAD();
00312 rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
00313 VALUE bindval = binding_alloc(rb_cBinding);
00314 rb_binding_t *bind;
00315
00316 if (cfp == 0) {
00317 rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
00318 }
00319
00320 GetBindingPtr(bindval, bind);
00321 bind->env = rb_vm_make_env_object(th, cfp);
00322 bind->filename = cfp->iseq->filename;
00323 bind->line_no = rb_vm_get_sourceline(cfp);
00324 return bindval;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 static VALUE
00344 rb_f_binding(VALUE self)
00345 {
00346 return rb_binding_new();
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 static VALUE
00366 bind_eval(int argc, VALUE *argv, VALUE bindval)
00367 {
00368 VALUE args[4];
00369
00370 rb_scan_args(argc, argv, "12", &args[0], &args[2], &args[3]);
00371 args[1] = bindval;
00372 return rb_f_eval(argc+1, args, Qnil );
00373 }
00374
00375 static VALUE
00376 proc_new(VALUE klass, int is_lambda)
00377 {
00378 VALUE procval = Qnil;
00379 rb_thread_t *th = GET_THREAD();
00380 rb_control_frame_t *cfp = th->cfp;
00381 rb_block_t *block;
00382
00383 if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) {
00384
00385 block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
00386 }
00387 else {
00388 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
00389
00390 if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) {
00391
00392 block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
00393
00394 if (is_lambda) {
00395 rb_warn("tried to create Proc object without a block");
00396 }
00397 }
00398 else {
00399 rb_raise(rb_eArgError,
00400 "tried to create Proc object without a block");
00401 }
00402 }
00403
00404 procval = block->proc;
00405
00406 if (procval) {
00407 if (RBASIC(procval)->klass == klass) {
00408 return procval;
00409 }
00410 else {
00411 VALUE newprocval = proc_dup(procval);
00412 RBASIC(newprocval)->klass = klass;
00413 return newprocval;
00414 }
00415 }
00416
00417 procval = rb_vm_make_proc(th, block, klass);
00418
00419 if (is_lambda) {
00420 rb_proc_t *proc;
00421 GetProcPtr(procval, proc);
00422 proc->is_lambda = TRUE;
00423 }
00424 return procval;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 static VALUE
00445 rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
00446 {
00447 VALUE block = proc_new(klass, FALSE);
00448
00449 rb_obj_call_init(block, argc, argv);
00450 return block;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460 VALUE
00461 rb_block_proc(void)
00462 {
00463 return proc_new(rb_cProc, FALSE);
00464 }
00465
00466 VALUE
00467 rb_block_lambda(void)
00468 {
00469 return proc_new(rb_cProc, TRUE);
00470 }
00471
00472 VALUE
00473 rb_f_lambda(void)
00474 {
00475 rb_warn("rb_f_lambda() is deprecated; use rb_block_proc() instead");
00476 return rb_block_lambda();
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 static VALUE
00488 proc_lambda(void)
00489 {
00490 return rb_block_lambda();
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 static VALUE
00538 proc_call(int argc, VALUE *argv, VALUE procval)
00539 {
00540 rb_proc_t *proc;
00541 rb_block_t *blockptr = 0;
00542 rb_iseq_t *iseq;
00543 VALUE passed_procval;
00544 GetProcPtr(procval, proc);
00545
00546 iseq = proc->block.iseq;
00547 if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) {
00548 if (rb_block_given_p()) {
00549 rb_proc_t *passed_proc;
00550 RB_GC_GUARD(passed_procval) = rb_block_proc();
00551 GetProcPtr(passed_procval, passed_proc);
00552 blockptr = &passed_proc->block;
00553 }
00554 }
00555
00556 return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
00557 argc, argv, blockptr);
00558 }
00559
00560 #if SIZEOF_LONG > SIZEOF_INT
00561 static inline int
00562 check_argc(long argc)
00563 {
00564 if (argc > INT_MAX || argc < 0) {
00565 rb_raise(rb_eArgError, "too many arguments (%lu)",
00566 (unsigned long)argc);
00567 }
00568 return (int)argc;
00569 }
00570 #else
00571 #define check_argc(argc) (argc)
00572 #endif
00573
00574 VALUE
00575 rb_proc_call(VALUE self, VALUE args)
00576 {
00577 rb_proc_t *proc;
00578 GetProcPtr(self, proc);
00579 return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
00580 check_argc(RARRAY_LEN(args)), RARRAY_PTR(args), 0);
00581 }
00582
00583 VALUE
00584 rb_proc_call_with_block(VALUE self, int argc, VALUE *argv, VALUE pass_procval)
00585 {
00586 rb_proc_t *proc;
00587 rb_block_t *block = 0;
00588 GetProcPtr(self, proc);
00589
00590 if (!NIL_P(pass_procval)) {
00591 rb_proc_t *pass_proc;
00592 GetProcPtr(pass_procval, pass_proc);
00593 block = &pass_proc->block;
00594 }
00595
00596 return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
00597 argc, argv, block);
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 static VALUE
00622 proc_arity(VALUE self)
00623 {
00624 int arity = rb_proc_arity(self);
00625 return INT2FIX(arity);
00626 }
00627
00628 int
00629 rb_proc_arity(VALUE self)
00630 {
00631 rb_proc_t *proc;
00632 rb_iseq_t *iseq;
00633 GetProcPtr(self, proc);
00634 iseq = proc->block.iseq;
00635 if (iseq) {
00636 if (BUILTIN_TYPE(iseq) != T_NODE) {
00637 if (iseq->arg_rest < 0) {
00638 return iseq->argc;
00639 }
00640 else {
00641 return -(iseq->argc + 1 + iseq->arg_post_len);
00642 }
00643 }
00644 else {
00645 NODE *node = (NODE *)iseq;
00646 if (IS_METHOD_PROC_NODE(node)) {
00647
00648 return method_arity(node->nd_tval);
00649 }
00650 }
00651 }
00652 return -1;
00653 }
00654
00655 #define get_proc_iseq rb_proc_get_iseq
00656
00657 rb_iseq_t *
00658 rb_proc_get_iseq(VALUE self, int *is_proc)
00659 {
00660 rb_proc_t *proc;
00661 rb_iseq_t *iseq;
00662
00663 GetProcPtr(self, proc);
00664 iseq = proc->block.iseq;
00665 if (is_proc) *is_proc = !proc->is_lambda;
00666 if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) {
00667 NODE *node = (NODE *)iseq;
00668 iseq = 0;
00669 if (IS_METHOD_PROC_NODE(node)) {
00670
00671 iseq = rb_method_get_iseq(node->nd_tval);
00672 if (is_proc) *is_proc = 0;
00673 }
00674 }
00675 return iseq;
00676 }
00677
00678 static VALUE
00679 iseq_location(rb_iseq_t *iseq)
00680 {
00681 VALUE loc[2];
00682
00683 if (!iseq) return Qnil;
00684 loc[0] = iseq->filename;
00685 if (iseq->insn_info_table) {
00686 loc[1] = INT2FIX(rb_iseq_first_lineno(iseq));
00687 }
00688 else {
00689 loc[1] = Qnil;
00690 }
00691 return rb_ary_new4(2, loc);
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 VALUE
00703 rb_proc_location(VALUE self)
00704 {
00705 return iseq_location(get_proc_iseq(self, 0));
00706 }
00707
00708 static VALUE
00709 unnamed_parameters(int arity)
00710 {
00711 VALUE a, param = rb_ary_new2((arity < 0) ? -arity : arity);
00712 int n = (arity < 0) ? ~arity : arity;
00713 ID req, rest;
00714 CONST_ID(req, "req");
00715 a = rb_ary_new3(1, ID2SYM(req));
00716 OBJ_FREEZE(a);
00717 for (; n; --n) {
00718 rb_ary_push(param, a);
00719 }
00720 if (arity < 0) {
00721 CONST_ID(rest, "rest");
00722 rb_ary_store(param, ~arity, rb_ary_new3(1, ID2SYM(rest)));
00723 }
00724 return param;
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 static VALUE
00738 rb_proc_parameters(VALUE self)
00739 {
00740 int is_proc;
00741 rb_iseq_t *iseq = get_proc_iseq(self, &is_proc);
00742 if (!iseq) {
00743 return unnamed_parameters(rb_proc_arity(self));
00744 }
00745 return rb_iseq_parameters(iseq, is_proc);
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 static VALUE
00757 proc_eq(VALUE self, VALUE other)
00758 {
00759 if (self == other) {
00760 return Qtrue;
00761 }
00762 else {
00763 if (rb_obj_is_proc(other)) {
00764 rb_proc_t *p1, *p2;
00765 GetProcPtr(self, p1);
00766 GetProcPtr(other, p2);
00767 if (p1->envval == p2->envval &&
00768 p1->block.iseq->iseq_size == p2->block.iseq->iseq_size &&
00769 p1->block.iseq->local_size == p2->block.iseq->local_size &&
00770 MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq, VALUE,
00771 p1->block.iseq->iseq_size) == 0) {
00772 return Qtrue;
00773 }
00774 }
00775 }
00776 return Qfalse;
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786 static VALUE
00787 proc_hash(VALUE self)
00788 {
00789 st_index_t hash;
00790 rb_proc_t *proc;
00791 GetProcPtr(self, proc);
00792 hash = rb_hash_start((st_index_t)proc->block.iseq);
00793 hash = rb_hash_uint(hash, (st_index_t)proc->envval);
00794 hash = rb_hash_uint(hash, (st_index_t)proc->block.lfp >> 16);
00795 hash = rb_hash_end(hash);
00796 return LONG2FIX(hash);
00797 }
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 static VALUE
00808 proc_to_s(VALUE self)
00809 {
00810 VALUE str = 0;
00811 rb_proc_t *proc;
00812 const char *cname = rb_obj_classname(self);
00813 rb_iseq_t *iseq;
00814 const char *is_lambda;
00815
00816 GetProcPtr(self, proc);
00817 iseq = proc->block.iseq;
00818 is_lambda = proc->is_lambda ? " (lambda)" : "";
00819
00820 if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
00821 int line_no = 0;
00822
00823 if (iseq->insn_info_table) {
00824 line_no = rb_iseq_first_lineno(iseq);
00825 }
00826 str = rb_sprintf("#<%s:%p@%s:%d%s>", cname, (void *)self,
00827 RSTRING_PTR(iseq->filename),
00828 line_no, is_lambda);
00829 }
00830 else {
00831 str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
00832 is_lambda);
00833 }
00834
00835 if (OBJ_TAINTED(self)) {
00836 OBJ_TAINT(str);
00837 }
00838 return str;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 static VALUE
00851 proc_to_proc(VALUE self)
00852 {
00853 return self;
00854 }
00855
00856 static void
00857 bm_mark(void *ptr)
00858 {
00859 struct METHOD *data = ptr;
00860 rb_gc_mark(data->rclass);
00861 rb_gc_mark(data->recv);
00862 rb_mark_method_entry(&data->me);
00863 }
00864
00865 static void
00866 bm_free(void *ptr)
00867 {
00868 struct METHOD *data = ptr;
00869 rb_method_definition_t *def = data->me.def;
00870 if (def->alias_count == 0)
00871 xfree(def);
00872 else if (def->alias_count > 0)
00873 def->alias_count--;
00874 xfree(ptr);
00875 }
00876
00877 static size_t
00878 bm_memsize(const void *ptr)
00879 {
00880 return ptr ? sizeof(struct METHOD) : 0;
00881 }
00882
00883 static const rb_data_type_t method_data_type = {
00884 "method",
00885 bm_mark,
00886 bm_free,
00887 bm_memsize,
00888 };
00889
00890 static inline int
00891 rb_obj_is_method(VALUE m)
00892 {
00893 return rb_typeddata_is_kind_of(m, &method_data_type);
00894 }
00895
00896 static VALUE
00897 mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)
00898 {
00899 VALUE method;
00900 VALUE rclass = klass;
00901 ID rid = id;
00902 struct METHOD *data;
00903 rb_method_entry_t *me, meb;
00904 rb_method_definition_t *def = 0;
00905 rb_method_flag_t flag = NOEX_UNDEF;
00906
00907 again:
00908 me = rb_method_entry(klass, id);
00909 if (UNDEFINED_METHOD_ENTRY_P(me)) {
00910 ID rmiss = rb_intern("respond_to_missing?");
00911 VALUE sym = ID2SYM(id);
00912
00913 if (obj != Qundef && !rb_method_basic_definition_p(klass, rmiss)) {
00914 if (RTEST(rb_funcall(obj, rmiss, 2, sym, scope ? Qfalse : Qtrue))) {
00915 def = ALLOC(rb_method_definition_t);
00916 def->type = VM_METHOD_TYPE_MISSING;
00917 def->original_id = id;
00918 def->alias_count = 0;
00919
00920 meb.flag = 0;
00921 meb.mark = 0;
00922 meb.called_id = id;
00923 meb.klass = klass;
00924 meb.def = def;
00925 me = &meb;
00926 def = 0;
00927
00928 goto gen_method;
00929 }
00930 }
00931 rb_print_undef(klass, id, 0);
00932 }
00933 def = me->def;
00934 if (flag == NOEX_UNDEF) {
00935 flag = me->flag;
00936 if (scope && (flag & NOEX_MASK) != NOEX_PUBLIC) {
00937 const char *v = "";
00938 switch (flag & NOEX_MASK) {
00939 case NOEX_PRIVATE: v = "private"; break;
00940 case NOEX_PROTECTED: v = "protected"; break;
00941 }
00942 rb_name_error(id, "method `%s' for %s `%s' is %s",
00943 rb_id2name(id),
00944 (TYPE(klass) == T_MODULE) ? "module" : "class",
00945 rb_class2name(klass),
00946 v);
00947 }
00948 }
00949 if (def && def->type == VM_METHOD_TYPE_ZSUPER) {
00950 klass = RCLASS_SUPER(me->klass);
00951 id = def->original_id;
00952 goto again;
00953 }
00954
00955 klass = me->klass;
00956
00957 while (rclass != klass &&
00958 (FL_TEST(rclass, FL_SINGLETON) || TYPE(rclass) == T_ICLASS)) {
00959 rclass = RCLASS_SUPER(rclass);
00960 }
00961
00962 if (TYPE(klass) == T_ICLASS) {
00963 klass = RBASIC(klass)->klass;
00964 }
00965
00966 gen_method:
00967 method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
00968
00969 data->recv = obj;
00970 data->rclass = rclass;
00971 data->id = rid;
00972 data->me = *me;
00973 if (def) def->alias_count++;
00974
00975 OBJ_INFECT(method, klass);
00976
00977 return method;
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 static VALUE
01014 method_eq(VALUE method, VALUE other)
01015 {
01016 struct METHOD *m1, *m2;
01017 extern int rb_method_entry_eq(rb_method_entry_t *m1, rb_method_entry_t *m2);
01018
01019 if (!rb_obj_is_method(other))
01020 return Qfalse;
01021 if (CLASS_OF(method) != CLASS_OF(other))
01022 return Qfalse;
01023
01024 Check_TypedStruct(method, &method_data_type);
01025 m1 = (struct METHOD *)DATA_PTR(method);
01026 m2 = (struct METHOD *)DATA_PTR(other);
01027
01028 if (!rb_method_entry_eq(&m1->me, &m2->me) ||
01029 m1->rclass != m2->rclass ||
01030 m1->recv != m2->recv) {
01031 return Qfalse;
01032 }
01033
01034 return Qtrue;
01035 }
01036
01037
01038
01039
01040
01041
01042
01043
01044 static VALUE
01045 method_hash(VALUE method)
01046 {
01047 struct METHOD *m;
01048 st_index_t hash;
01049
01050 TypedData_Get_Struct(method, struct METHOD, &method_data_type, m);
01051 hash = rb_hash_start((st_index_t)m->rclass);
01052 hash = rb_hash_uint(hash, (st_index_t)m->recv);
01053 hash = rb_hash_uint(hash, (st_index_t)m->me.def);
01054 hash = rb_hash_end(hash);
01055
01056 return INT2FIX(hash);
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068 static VALUE
01069 method_unbind(VALUE obj)
01070 {
01071 VALUE method;
01072 struct METHOD *orig, *data;
01073
01074 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, orig);
01075 method = TypedData_Make_Struct(rb_cUnboundMethod, struct METHOD,
01076 &method_data_type, data);
01077 data->recv = Qundef;
01078 data->id = orig->id;
01079 data->me = orig->me;
01080 if (orig->me.def) orig->me.def->alias_count++;
01081 data->rclass = orig->rclass;
01082 OBJ_INFECT(method, obj);
01083
01084 return method;
01085 }
01086
01087
01088
01089
01090
01091
01092
01093
01094 static VALUE
01095 method_receiver(VALUE obj)
01096 {
01097 struct METHOD *data;
01098
01099 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
01100 return data->recv;
01101 }
01102
01103
01104
01105
01106
01107
01108
01109
01110 static VALUE
01111 method_name(VALUE obj)
01112 {
01113 struct METHOD *data;
01114
01115 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
01116 return ID2SYM(data->id);
01117 }
01118
01119
01120
01121
01122
01123
01124
01125
01126 static VALUE
01127 method_owner(VALUE obj)
01128 {
01129 struct METHOD *data;
01130
01131 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
01132 return data->me.klass;
01133 }
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 VALUE
01164 rb_obj_method(VALUE obj, VALUE vid)
01165 {
01166 return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod, FALSE);
01167 }
01168
01169
01170
01171
01172
01173
01174
01175
01176 VALUE
01177 rb_obj_public_method(VALUE obj, VALUE vid)
01178 {
01179 return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod, TRUE);
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 static VALUE
01214 rb_mod_instance_method(VALUE mod, VALUE vid)
01215 {
01216 return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod, FALSE);
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226 static VALUE
01227 rb_mod_public_instance_method(VALUE mod, VALUE vid)
01228 {
01229 return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod, TRUE);
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269 static VALUE
01270 rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
01271 {
01272 ID id;
01273 VALUE body;
01274 int noex = NOEX_PUBLIC;
01275
01276 if (argc == 1) {
01277 id = rb_to_id(argv[0]);
01278 body = rb_block_lambda();
01279 }
01280 else if (argc == 2) {
01281 id = rb_to_id(argv[0]);
01282 body = argv[1];
01283 if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) {
01284 rb_raise(rb_eTypeError,
01285 "wrong argument type %s (expected Proc/Method)",
01286 rb_obj_classname(body));
01287 }
01288 }
01289 else {
01290 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
01291 }
01292
01293 if (rb_obj_is_method(body)) {
01294 struct METHOD *method = (struct METHOD *)DATA_PTR(body);
01295 VALUE rclass = method->rclass;
01296 if (rclass != mod && !RTEST(rb_class_inherited_p(mod, rclass))) {
01297 if (FL_TEST(rclass, FL_SINGLETON)) {
01298 rb_raise(rb_eTypeError,
01299 "can't bind singleton method to a different class");
01300 }
01301 else {
01302 rb_raise(rb_eTypeError,
01303 "bind argument must be a subclass of %s",
01304 rb_class2name(rclass));
01305 }
01306 }
01307 rb_method_entry_set(mod, id, &method->me, noex);
01308 }
01309 else if (rb_obj_is_proc(body)) {
01310 rb_proc_t *proc;
01311 body = proc_dup(body);
01312 GetProcPtr(body, proc);
01313 if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) {
01314 proc->block.iseq->defined_method_id = id;
01315 proc->block.iseq->klass = mod;
01316 proc->is_lambda = TRUE;
01317 proc->is_from_method = TRUE;
01318 }
01319 rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)body, noex);
01320 }
01321 else {
01322
01323 rb_raise(rb_eTypeError, "wrong argument type (expected Proc/Method)");
01324 }
01325
01326 return body;
01327 }
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355 static VALUE
01356 rb_obj_define_method(int argc, VALUE *argv, VALUE obj)
01357 {
01358 VALUE klass = rb_singleton_class(obj);
01359
01360 return rb_mod_define_method(argc, argv, klass);
01361 }
01362
01363
01364
01365
01366
01367
01368 static VALUE
01369 method_clone(VALUE self)
01370 {
01371 VALUE clone;
01372 struct METHOD *orig, *data;
01373
01374 TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
01375 clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data);
01376 CLONESETUP(clone, self);
01377 *data = *orig;
01378 if (data->me.def) data->me.def->alias_count++;
01379
01380 return clone;
01381 }
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 VALUE
01397 rb_method_call(int argc, VALUE *argv, VALUE method)
01398 {
01399 VALUE result = Qnil;
01400 struct METHOD *data;
01401 int state;
01402 volatile int safe = -1;
01403
01404 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
01405 if (data->recv == Qundef) {
01406 rb_raise(rb_eTypeError, "can't call unbound method; bind first");
01407 }
01408 PUSH_TAG();
01409 if (OBJ_TAINTED(method)) {
01410 safe = rb_safe_level();
01411 if (rb_safe_level() < 4) {
01412 rb_set_safe_level_force(4);
01413 }
01414 }
01415 if ((state = EXEC_TAG()) == 0) {
01416 rb_thread_t *th = GET_THREAD();
01417 VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv,
01418 const rb_method_entry_t *me);
01419
01420 PASS_PASSED_BLOCK_TH(th);
01421 result = rb_vm_call(th, data->recv, data->id, argc, argv, &data->me);
01422 }
01423 POP_TAG();
01424 if (safe >= 0)
01425 rb_set_safe_level_force(safe);
01426 if (state)
01427 JUMP_TAG(state);
01428 return result;
01429 }
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 static VALUE
01523 umethod_bind(VALUE method, VALUE recv)
01524 {
01525 struct METHOD *data, *bound;
01526
01527 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
01528
01529 if (data->rclass != CLASS_OF(recv) && !rb_obj_is_kind_of(recv, data->rclass)) {
01530 if (FL_TEST(data->rclass, FL_SINGLETON)) {
01531 rb_raise(rb_eTypeError,
01532 "singleton method called for a different object");
01533 }
01534 else {
01535 rb_raise(rb_eTypeError, "bind argument must be an instance of %s",
01536 rb_class2name(data->rclass));
01537 }
01538 }
01539
01540 method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
01541 *bound = *data;
01542 if (bound->me.def) bound->me.def->alias_count++;
01543 bound->recv = recv;
01544 bound->rclass = CLASS_OF(recv);
01545
01546 return method;
01547 }
01548
01549 int
01550 rb_method_entry_arity(const rb_method_entry_t *me)
01551 {
01552 const rb_method_definition_t *def = me->def;
01553 if (!def) return 0;
01554 switch (def->type) {
01555 case VM_METHOD_TYPE_CFUNC:
01556 if (def->body.cfunc.argc < 0)
01557 return -1;
01558 return check_argc(def->body.cfunc.argc);
01559 case VM_METHOD_TYPE_ZSUPER:
01560 return -1;
01561 case VM_METHOD_TYPE_ATTRSET:
01562 return 1;
01563 case VM_METHOD_TYPE_IVAR:
01564 return 0;
01565 case VM_METHOD_TYPE_BMETHOD:
01566 return rb_proc_arity(def->body.proc);
01567 case VM_METHOD_TYPE_ISEQ: {
01568 rb_iseq_t *iseq = def->body.iseq;
01569 if (iseq->arg_rest == -1 && iseq->arg_opts == 0) {
01570 return iseq->argc;
01571 }
01572 else {
01573 return -(iseq->argc + 1 + iseq->arg_post_len);
01574 }
01575 }
01576 case VM_METHOD_TYPE_UNDEF:
01577 case VM_METHOD_TYPE_NOTIMPLEMENTED:
01578 return 0;
01579 case VM_METHOD_TYPE_MISSING:
01580 return -1;
01581 case VM_METHOD_TYPE_OPTIMIZED: {
01582 switch (def->body.optimize_type) {
01583 case OPTIMIZED_METHOD_TYPE_SEND:
01584 return -1;
01585 default:
01586 break;
01587 }
01588 }
01589 }
01590 rb_bug("rb_method_entry_arity: invalid method entry type (%d)", def->type);
01591 }
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626 static VALUE
01627 method_arity_m(VALUE method)
01628 {
01629 int n = method_arity(method);
01630 return INT2FIX(n);
01631 }
01632
01633 static int
01634 method_arity(VALUE method)
01635 {
01636 struct METHOD *data;
01637
01638 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
01639 return rb_method_entry_arity(&data->me);
01640 }
01641
01642 int
01643 rb_mod_method_arity(VALUE mod, ID id)
01644 {
01645 rb_method_entry_t *me = rb_method_entry(mod, id);
01646 return rb_method_entry_arity(me);
01647 }
01648
01649 int
01650 rb_obj_method_arity(VALUE obj, ID id)
01651 {
01652 return rb_mod_method_arity(CLASS_OF(obj), id);
01653 }
01654
01655 static inline rb_method_definition_t *
01656 method_get_def(VALUE method)
01657 {
01658 struct METHOD *data;
01659
01660 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
01661 return data->me.def;
01662 }
01663
01664 static rb_iseq_t *
01665 method_get_iseq(rb_method_definition_t *def)
01666 {
01667 switch (def->type) {
01668 case VM_METHOD_TYPE_BMETHOD:
01669 return get_proc_iseq(def->body.proc, 0);
01670 case VM_METHOD_TYPE_ISEQ:
01671 return def->body.iseq;
01672 default:
01673 return 0;
01674 }
01675 }
01676
01677 rb_iseq_t *
01678 rb_method_get_iseq(VALUE method)
01679 {
01680 return method_get_iseq(method_get_def(method));
01681 }
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691 VALUE
01692 rb_method_location(VALUE method)
01693 {
01694 rb_method_definition_t *def = method_get_def(method);
01695 if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
01696 if (!def->body.attr.location)
01697 return Qnil;
01698 return rb_ary_dup(def->body.attr.location);
01699 }
01700 return iseq_location(method_get_iseq(def));
01701 }
01702
01703
01704
01705
01706
01707
01708
01709
01710 static VALUE
01711 rb_method_parameters(VALUE method)
01712 {
01713 rb_iseq_t *iseq = rb_method_get_iseq(method);
01714 if (!iseq) {
01715 return unnamed_parameters(method_arity(method));
01716 }
01717 return rb_iseq_parameters(iseq, 0);
01718 }
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730 static VALUE
01731 method_inspect(VALUE method)
01732 {
01733 struct METHOD *data;
01734 VALUE str;
01735 const char *s;
01736 const char *sharp = "#";
01737
01738 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
01739 str = rb_str_buf_new2("#<");
01740 s = rb_obj_classname(method);
01741 rb_str_buf_cat2(str, s);
01742 rb_str_buf_cat2(str, ": ");
01743
01744 if (FL_TEST(data->me.klass, FL_SINGLETON)) {
01745 VALUE v = rb_iv_get(data->me.klass, "__attached__");
01746
01747 if (data->recv == Qundef) {
01748 rb_str_buf_append(str, rb_inspect(data->me.klass));
01749 }
01750 else if (data->recv == v) {
01751 rb_str_buf_append(str, rb_inspect(v));
01752 sharp = ".";
01753 }
01754 else {
01755 rb_str_buf_append(str, rb_inspect(data->recv));
01756 rb_str_buf_cat2(str, "(");
01757 rb_str_buf_append(str, rb_inspect(v));
01758 rb_str_buf_cat2(str, ")");
01759 sharp = ".";
01760 }
01761 }
01762 else {
01763 rb_str_buf_cat2(str, rb_class2name(data->rclass));
01764 if (data->rclass != data->me.klass) {
01765 rb_str_buf_cat2(str, "(");
01766 rb_str_buf_cat2(str, rb_class2name(data->me.klass));
01767 rb_str_buf_cat2(str, ")");
01768 }
01769 }
01770 rb_str_buf_cat2(str, sharp);
01771 rb_str_append(str, rb_id2str(data->me.def->original_id));
01772 if (data->me.def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
01773 rb_str_buf_cat2(str, " (not-implemented)");
01774 }
01775 rb_str_buf_cat2(str, ">");
01776
01777 return str;
01778 }
01779
01780 static VALUE
01781 mproc(VALUE method)
01782 {
01783 return rb_funcall(Qnil, rb_intern("proc"), 0);
01784 }
01785
01786 static VALUE
01787 mlambda(VALUE method)
01788 {
01789 return rb_funcall(Qnil, rb_intern("lambda"), 0);
01790 }
01791
01792 static VALUE
01793 bmcall(VALUE args, VALUE method)
01794 {
01795 volatile VALUE a;
01796 VALUE ret;
01797 int argc;
01798
01799 if (CLASS_OF(args) != rb_cArray) {
01800 args = rb_ary_new3(1, args);
01801 argc = 1;
01802 }
01803 else {
01804 argc = check_argc(RARRAY_LEN(args));
01805 }
01806 ret = rb_method_call(argc, RARRAY_PTR(args), method);
01807 RB_GC_GUARD(a) = args;
01808 return ret;
01809 }
01810
01811 VALUE
01812 rb_proc_new(
01813 VALUE (*func)(ANYARGS),
01814 VALUE val)
01815 {
01816 VALUE procval = rb_iterate(mproc, 0, func, val);
01817 return procval;
01818 }
01819
01820
01821
01822
01823
01824
01825
01826
01827 static VALUE
01828 method_proc(VALUE method)
01829 {
01830 VALUE procval;
01831 rb_proc_t *proc;
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841 procval = rb_iterate(mlambda, 0, bmcall, method);
01842 GetProcPtr(procval, proc);
01843 proc->is_from_method = 1;
01844 return procval;
01845 }
01846
01847
01848
01849
01850
01851
01852
01853 static VALUE
01854 localjump_xvalue(VALUE exc)
01855 {
01856 return rb_iv_get(exc, "@exit_value");
01857 }
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867 static VALUE
01868 localjump_reason(VALUE exc)
01869 {
01870 return rb_iv_get(exc, "@reason");
01871 }
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888 static VALUE
01889 proc_binding(VALUE self)
01890 {
01891 rb_proc_t *proc;
01892 VALUE bindval;
01893 rb_binding_t *bind;
01894
01895 GetProcPtr(self, proc);
01896 if (TYPE(proc->block.iseq) == T_NODE) {
01897 if (!IS_METHOD_PROC_NODE((NODE *)proc->block.iseq)) {
01898 rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
01899 }
01900 }
01901
01902 bindval = binding_alloc(rb_cBinding);
01903 GetBindingPtr(bindval, bind);
01904 bind->env = proc->envval;
01905 if (RUBY_VM_NORMAL_ISEQ_P(proc->block.iseq)) {
01906 bind->filename = proc->block.iseq->filename;
01907 bind->line_no = rb_iseq_first_lineno(proc->block.iseq);
01908 }
01909 else {
01910 bind->filename = Qnil;
01911 bind->line_no = 0;
01912 }
01913 return bindval;
01914 }
01915
01916 static VALUE curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc);
01917
01918 static VALUE
01919 make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
01920 {
01921 VALUE args = rb_ary_new3(3, proc, passed, arity);
01922 rb_proc_t *procp;
01923 int is_lambda;
01924
01925 GetProcPtr(proc, procp);
01926 is_lambda = procp->is_lambda;
01927 rb_ary_freeze(passed);
01928 rb_ary_freeze(args);
01929 proc = rb_proc_new(curry, args);
01930 GetProcPtr(proc, procp);
01931 procp->is_lambda = is_lambda;
01932 return proc;
01933 }
01934
01935 static VALUE
01936 curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc)
01937 {
01938 VALUE proc, passed, arity;
01939 proc = RARRAY_PTR(args)[0];
01940 passed = RARRAY_PTR(args)[1];
01941 arity = RARRAY_PTR(args)[2];
01942
01943 passed = rb_ary_plus(passed, rb_ary_new4(argc, argv));
01944 rb_ary_freeze(passed);
01945
01946 if (RARRAY_LEN(passed) < FIX2INT(arity)) {
01947 if (!NIL_P(passed_proc)) {
01948 rb_warn("given block not used");
01949 }
01950 arity = make_curry_proc(proc, passed, arity);
01951 return arity;
01952 }
01953 else {
01954 return rb_proc_call_with_block(proc, check_argc(RARRAY_LEN(passed)),
01955 RARRAY_PTR(passed), passed_proc);
01956 }
01957 }
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001 static VALUE
02002 proc_curry(int argc, VALUE *argv, VALUE self)
02003 {
02004 int sarity, marity = rb_proc_arity(self);
02005 VALUE arity, opt = Qfalse;
02006
02007 if (marity < 0) {
02008 marity = -marity - 1;
02009 opt = Qtrue;
02010 }
02011
02012 rb_scan_args(argc, argv, "01", &arity);
02013 if (NIL_P(arity)) {
02014 arity = INT2FIX(marity);
02015 }
02016 else {
02017 sarity = FIX2INT(arity);
02018 if (rb_proc_lambda_p(self) && (sarity < marity || (sarity > marity && !opt))) {
02019 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", sarity, marity);
02020 }
02021 }
02022
02023 return make_curry_proc(self, rb_ary_new(), arity);
02024 }
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087 void
02088 Init_Proc(void)
02089 {
02090
02091 rb_cProc = rb_define_class("Proc", rb_cObject);
02092 rb_undef_alloc_func(rb_cProc);
02093 rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1);
02094
02095 #if 0
02096 rb_add_method(rb_cProc, rb_intern("call"), VM_METHOD_TYPE_OPTIMIZED,
02097 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0);
02098 rb_add_method(rb_cProc, rb_intern("[]"), VM_METHOD_TYPE_OPTIMIZED,
02099 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0);
02100 rb_add_method(rb_cProc, rb_intern("==="), VM_METHOD_TYPE_OPTIMIZED,
02101 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0);
02102 rb_add_method(rb_cProc, rb_intern("yield"), VM_METHOD_TYPE_OPTIMIZED,
02103 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0);
02104 #else
02105 rb_define_method(rb_cProc, "call", proc_call, -1);
02106 rb_define_method(rb_cProc, "[]", proc_call, -1);
02107 rb_define_method(rb_cProc, "===", proc_call, -1);
02108 rb_define_method(rb_cProc, "yield", proc_call, -1);
02109 #endif
02110 rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
02111 rb_define_method(rb_cProc, "arity", proc_arity, 0);
02112 rb_define_method(rb_cProc, "clone", proc_clone, 0);
02113 rb_define_method(rb_cProc, "dup", proc_dup, 0);
02114 rb_define_method(rb_cProc, "==", proc_eq, 1);
02115 rb_define_method(rb_cProc, "eql?", proc_eq, 1);
02116 rb_define_method(rb_cProc, "hash", proc_hash, 0);
02117 rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
02118 rb_define_method(rb_cProc, "lambda?", rb_proc_lambda_p, 0);
02119 rb_define_method(rb_cProc, "binding", proc_binding, 0);
02120 rb_define_method(rb_cProc, "curry", proc_curry, -1);
02121 rb_define_method(rb_cProc, "source_location", rb_proc_location, 0);
02122 rb_define_method(rb_cProc, "parameters", rb_proc_parameters, 0);
02123
02124
02125 rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
02126 rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
02127 rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
02128
02129 rb_eSysStackError = rb_define_class("SystemStackError", rb_eException);
02130 sysstack_error = rb_exc_new3(rb_eSysStackError,
02131 rb_obj_freeze(rb_str_new2("stack level too deep")));
02132 OBJ_TAINT(sysstack_error);
02133
02134
02135 rb_define_global_function("proc", rb_block_proc, 0);
02136 rb_define_global_function("lambda", proc_lambda, 0);
02137
02138
02139 rb_cMethod = rb_define_class("Method", rb_cObject);
02140 rb_undef_alloc_func(rb_cMethod);
02141 rb_undef_method(CLASS_OF(rb_cMethod), "new");
02142 rb_define_method(rb_cMethod, "==", method_eq, 1);
02143 rb_define_method(rb_cMethod, "eql?", method_eq, 1);
02144 rb_define_method(rb_cMethod, "hash", method_hash, 0);
02145 rb_define_method(rb_cMethod, "clone", method_clone, 0);
02146 rb_define_method(rb_cMethod, "call", rb_method_call, -1);
02147 rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
02148 rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
02149 rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
02150 rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
02151 rb_define_method(rb_cMethod, "to_proc", method_proc, 0);
02152 rb_define_method(rb_cMethod, "receiver", method_receiver, 0);
02153 rb_define_method(rb_cMethod, "name", method_name, 0);
02154 rb_define_method(rb_cMethod, "owner", method_owner, 0);
02155 rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
02156 rb_define_method(rb_cMethod, "source_location", rb_method_location, 0);
02157 rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0);
02158 rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
02159 rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
02160
02161
02162 rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
02163 rb_undef_alloc_func(rb_cUnboundMethod);
02164 rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new");
02165 rb_define_method(rb_cUnboundMethod, "==", method_eq, 1);
02166 rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1);
02167 rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
02168 rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
02169 rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
02170 rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
02171 rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
02172 rb_define_method(rb_cUnboundMethod, "name", method_name, 0);
02173 rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0);
02174 rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
02175 rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0);
02176 rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0);
02177
02178
02179 rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);
02180 rb_define_method(rb_cModule, "public_instance_method", rb_mod_public_instance_method, 1);
02181 rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1);
02182
02183
02184 rb_define_method(rb_mKernel, "define_singleton_method", rb_obj_define_method, -1);
02185 }
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222 void
02223 Init_Binding(void)
02224 {
02225 rb_cBinding = rb_define_class("Binding", rb_cObject);
02226 rb_undef_alloc_func(rb_cBinding);
02227 rb_undef_method(CLASS_OF(rb_cBinding), "new");
02228 rb_define_method(rb_cBinding, "clone", binding_clone, 0);
02229 rb_define_method(rb_cBinding, "dup", binding_dup, 0);
02230 rb_define_method(rb_cBinding, "eval", bind_eval, -1);
02231 rb_define_global_function("binding", rb_f_binding, 0);
02232 }
02233
02234