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