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