Changeset 331 for EcnlProtoTool/trunk/mruby-1.3.0/src/kernel.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/src/kernel.c
r321 r331 5 5 */ 6 6 7 #include "mruby.h" 8 #include "mruby/array.h" 9 #include "mruby/class.h" 10 #include "mruby/proc.h" 11 #include "mruby/string.h" 12 #include "mruby/variable.h" 13 #include "mruby/error.h" 7 #include <mruby.h> 8 #include <mruby/array.h> 9 #include <mruby/hash.h> 10 #include <mruby/class.h> 11 #include <mruby/proc.h> 12 #include <mruby/string.h> 13 #include <mruby/variable.h> 14 #include <mruby/error.h> 15 #include <mruby/istruct.h> 14 16 15 17 typedef enum { … … 27 29 } mrb_method_flag_t; 28 30 31 MRB_API mrb_bool 32 mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func) 33 { 34 struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid); 35 if (MRB_PROC_CFUNC_P(me) && (me->body.func == func)) 36 return TRUE; 37 return FALSE; 38 } 39 29 40 static mrb_bool 30 41 mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj) 31 42 { 32 struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern_lit(mrb, "to_s")); 33 if (MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s)) 34 return TRUE; 35 return FALSE; 43 return mrb_func_basic_p(mrb, obj, mrb_intern_lit(mrb, "to_s"), mrb_any_to_s); 36 44 } 37 45 … … 57 65 } 58 66 return mrb_any_to_s(mrb, obj); 59 }60 61 /* 15.3.1.3.1 */62 /* 15.3.1.3.10 */63 /* 15.3.1.3.11 */64 /*65 * call-seq:66 * obj == other -> true or false67 * obj.equal?(other) -> true or false68 * obj.eql?(other) -> true or false69 *70 * Equality---At the <code>Object</code> level, <code>==</code> returns71 * <code>true</code> only if <i>obj</i> and <i>other</i> are the72 * same object. Typically, this method is overridden in descendant73 * classes to provide class-specific meaning.74 *75 * Unlike <code>==</code>, the <code>equal?</code> method should never be76 * overridden by subclasses: it is used to determine object identity77 * (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same78 * object as <code>b</code>).79 *80 * The <code>eql?</code> method returns <code>true</code> if81 * <i>obj</i> and <i>anObject</i> have the same value. Used by82 * <code>Hash</code> to test members for equality. For objects of83 * class <code>Object</code>, <code>eql?</code> is synonymous with84 * <code>==</code>. Subclasses normally continue this tradition, but85 * there are exceptions. <code>Numeric</code> types, for example,86 * perform type conversion across <code>==</code>, but not across87 * <code>eql?</code>, so:88 *89 * 1 == 1.0 #=> true90 * 1.eql? 1.0 #=> false91 */92 static mrb_value93 mrb_obj_equal_m(mrb_state *mrb, mrb_value self)94 {95 mrb_value arg;96 97 mrb_get_args(mrb, "o", &arg);98 return mrb_bool_value(mrb_obj_equal(mrb, self, arg));99 }100 101 static mrb_value102 mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)103 {104 mrb_value arg;105 106 mrb_get_args(mrb, "o", &arg);107 return mrb_bool_value(!mrb_equal(mrb, self, arg));108 67 } 109 68 … … 143 102 * <code>name</code>. Replaces the deprecated <code>Object#id</code>. 144 103 */ 145 staticmrb_value104 mrb_value 146 105 mrb_obj_id_m(mrb_state *mrb, mrb_value self) 147 106 { … … 178 137 mrb_callinfo *ci = mrb->c->ci; 179 138 mrb_value *bp; 180 mrb_bool given_p;181 139 182 140 bp = ci->stackent + 1; 183 141 ci--; 184 142 if (ci <= mrb->c->cibase) { 185 given_p = FALSE; 186 } 187 else { 188 /* block_given? called within block; check upper scope */ 189 if (ci->proc->env) { 190 struct REnv *e = ci->proc->env; 191 mrb_value *sp; 192 193 while (e->c) { 194 e = (struct REnv*)e->c; 195 } 196 sp = e->stack; 197 if (sp) { 198 /* top-level does not have block slot (alway false) */ 199 if (sp == mrb->c->stbase) 200 return mrb_false_value(); 201 ci = mrb->c->cibase + e->cioff; 202 bp = ci[1].stackent + 1; 203 } 204 } 205 if (ci->argc > 0) { 206 bp += ci->argc; 207 } 208 given_p = !mrb_nil_p(*bp); 209 } 210 211 return mrb_bool_value(given_p); 143 return mrb_false_value(); 144 } 145 /* block_given? called within block; check upper scope */ 146 if (ci->proc->env) { 147 struct REnv *e = ci->proc->env; 148 149 while (e->c) { 150 e = (struct REnv*)e->c; 151 } 152 /* top-level does not have block slot (always false) */ 153 if (e->stack == mrb->c->stbase) 154 return mrb_false_value(); 155 if (e->stack && e->cioff < 0) { 156 /* use saved block arg position */ 157 bp = &e->stack[-e->cioff]; 158 ci = 0; /* no callinfo available */ 159 } 160 else { 161 ci = e->cxt.c->cibase + e->cioff; 162 bp = ci[1].stackent + 1; 163 } 164 } 165 if (ci && ci->argc > 0) { 166 bp += ci->argc; 167 } 168 if (mrb_nil_p(*bp)) 169 return mrb_false_value(); 170 return mrb_true_value(); 212 171 } 213 172 … … 241 200 struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class); 242 201 243 if ((mrb_type(obj) == MRB_TT_CLASS) || (mrb_type(obj) == MRB_TT_SCLASS)) { 244 clone->c = clone; 245 } 246 else { 202 switch (mrb_type(obj)) { 203 case MRB_TT_CLASS: 204 case MRB_TT_SCLASS: 205 break; 206 default: 247 207 clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass)); 208 break; 248 209 } 249 210 clone->super = klass->super; … … 283 244 c1->super->flags |= MRB_FLAG_IS_ORIGIN; 284 245 } 285 dc->mt = kh_copy(mt, mrb, sc->mt); 246 if (sc->mt) { 247 dc->mt = kh_copy(mt, mrb, sc->mt); 248 } 249 else { 250 dc->mt = kh_init(mt, mrb); 251 } 286 252 dc->super = sc->super; 253 MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); 287 254 } 288 255 … … 302 269 mrb_iv_copy(mrb, dest, obj); 303 270 break; 271 case MRB_TT_ISTRUCT: 272 mrb_istruct_copy(dest, obj); 273 break; 304 274 305 275 default: … … 441 411 mrb_value *argv; 442 412 mrb_int argc; 413 mrb_value args; 443 414 444 415 mrb_get_args(mrb, "*", &argv, &argc); 416 args = mrb_ary_new_from_values(mrb, argc, argv); 417 argv = (mrb_value*)RARRAY_PTR(args); 445 418 return mrb_obj_extend(mrb, argc, argv, self); 419 } 420 421 static mrb_value 422 mrb_obj_freeze(mrb_state *mrb, mrb_value self) 423 { 424 struct RBasic *b; 425 426 switch (mrb_type(self)) { 427 case MRB_TT_FALSE: 428 case MRB_TT_TRUE: 429 case MRB_TT_FIXNUM: 430 case MRB_TT_SYMBOL: 431 case MRB_TT_FLOAT: 432 return self; 433 default: 434 break; 435 } 436 437 b = mrb_basic_ptr(self); 438 if (!MRB_FROZEN_P(b)) { 439 MRB_SET_FROZEN_FLAG(b); 440 } 441 return self; 442 } 443 444 static mrb_value 445 mrb_obj_frozen(mrb_state *mrb, mrb_value self) 446 { 447 struct RBasic *b; 448 449 switch (mrb_type(self)) { 450 case MRB_TT_FALSE: 451 case MRB_TT_TRUE: 452 case MRB_TT_FIXNUM: 453 case MRB_TT_SYMBOL: 454 case MRB_TT_FLOAT: 455 return mrb_true_value(); 456 default: 457 break; 458 } 459 460 b = mrb_basic_ptr(self); 461 if (!MRB_FROZEN_P(b)) { 462 return mrb_false_value(); 463 } 464 return mrb_true_value(); 446 465 } 447 466 … … 477 496 } 478 497 479 480 /* implementation of instance_eval */481 mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value);482 498 483 499 MRB_API mrb_bool … … 723 739 mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag) 724 740 { 725 if (recur) 726 return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0); 727 return mrb_obj_singleton_methods(mrb, recur, obj); 741 return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0); 728 742 } 729 743 /* 15.3.1.3.31 */ … … 853 867 break; 854 868 case 1: 855 a[1] = mrb_check_string_type(mrb, a[0]);856 if (!mrb_nil_p(a[1])) {869 if (mrb_string_p(a[0])) { 870 a[1] = a[0]; 857 871 argc = 2; 858 872 a[0] = mrb_obj_value(E_RUNTIME_ERROR); … … 861 875 default: 862 876 exc = mrb_make_exception(mrb, argc, a); 863 mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern_lit(mrb, "lastpc"), mrb_cptr_value(mrb, mrb->c->ci->pc));864 877 mrb_exc_raise(mrb, exc); 865 878 break; … … 905 918 } 906 919 920 void 921 mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) 922 { 923 mrb_sym inspect; 924 mrb_value repr; 925 926 inspect = mrb_intern_lit(mrb, "inspect"); 927 if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { 928 /* method missing in inspect; avoid recursion */ 929 repr = mrb_any_to_s(mrb, self); 930 } 931 else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) { 932 repr = mrb_funcall_argv(mrb, self, inspect, 0, 0); 933 if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) { 934 repr = mrb_any_to_s(mrb, self); 935 } 936 } 937 else { 938 repr = mrb_any_to_s(mrb, self); 939 } 940 941 mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S", 942 mrb_sym2str(mrb, name), repr); 943 } 944 945 /* 15.3.1.3.30 */ 946 /* 947 * call-seq: 948 * obj.method_missing(symbol [, *args] ) -> result 949 * 950 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle. 951 * <i>symbol</i> is the symbol for the method called, and <i>args</i> 952 * are any arguments that were passed to it. By default, the interpreter 953 * raises an error when this method is called. However, it is possible 954 * to override the method to provide more dynamic behavior. 955 * If it is decided that a particular method should not be handled, then 956 * <i>super</i> should be called, so that ancestors can pick up the 957 * missing method. 958 * The example below creates 959 * a class <code>Roman</code>, which responds to methods with names 960 * consisting of roman numerals, returning the corresponding integer 961 * values. 962 * 963 * class Roman 964 * def romanToInt(str) 965 * # ... 966 * end 967 * def method_missing(methId) 968 * str = methId.id2name 969 * romanToInt(str) 970 * end 971 * end 972 * 973 * r = Roman.new 974 * r.iv #=> 4 975 * r.xxiii #=> 23 976 * r.mm #=> 2000 977 */ 978 #ifdef MRB_DEFAULT_METHOD_MISSING 979 static mrb_value 980 mrb_obj_missing(mrb_state *mrb, mrb_value mod) 981 { 982 mrb_sym name; 983 mrb_value *a; 984 mrb_int alen; 985 986 mrb_get_args(mrb, "n*", &name, &a, &alen); 987 mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a)); 988 /* not reached */ 989 return mrb_nil_value(); 990 } 991 #endif 992 907 993 static inline mrb_bool 908 994 basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) … … 940 1026 else { 941 1027 mrb_value tmp; 942 if (!mrb_string_p(mid)) { 1028 if (mrb_string_p(mid)) { 1029 tmp = mrb_check_intern_str(mrb, mid); 1030 } 1031 else { 943 1032 tmp = mrb_check_string_type(mrb, mid); 944 1033 if (mrb_nil_p(tmp)) { … … 946 1035 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp); 947 1036 } 948 }949 tmp = mrb_check_intern_str(mrb, mid);1037 tmp = mrb_check_intern_str(mrb, tmp); 1038 } 950 1039 if (mrb_nil_p(tmp)) { 951 1040 respond_to_p = FALSE; … … 963 1052 rtm_id = mrb_intern_lit(mrb, "respond_to_missing?"); 964 1053 if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) { 965 mrb_value args[2] ;1054 mrb_value args[2], v; 966 1055 args[0] = mid; 967 1056 args[1] = mrb_bool_value(priv); 968 return mrb_funcall_argv(mrb, self, rtm_id, 2, args); 1057 v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); 1058 return mrb_bool_value(mrb_bool(v)); 969 1059 } 970 1060 } … … 1051 1141 mrb_local_variables(mrb_state *mrb, mrb_value self) 1052 1142 { 1053 mrb_value ret;1054 1143 struct RProc *proc; 1144 mrb_value vars; 1055 1145 struct mrb_irep *irep; 1056 1146 size_t i; … … 1066 1156 return mrb_ary_new(mrb); 1067 1157 } 1068 ret = mrb_ary_new_capa(mrb, irep->nlocals - 1);1158 vars = mrb_hash_new(mrb); 1069 1159 for (i = 0; i + 1 < irep->nlocals; ++i) { 1070 1160 if (irep->lv[i].name) { 1071 mrb_ ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));1161 mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value()); 1072 1162 } 1073 1163 } … … 1076 1166 1077 1167 while (e) { 1078 if (!MRB_PROC_CFUNC_P(mrb->c->cibase[e->cioff].proc)) { 1079 irep = mrb->c->cibase[e->cioff].proc->body.irep; 1168 if (MRB_ENV_STACK_SHARED_P(e) && 1169 !MRB_PROC_CFUNC_P(e->cxt.c->cibase[e->cioff].proc)) { 1170 irep = e->cxt.c->cibase[e->cioff].proc->body.irep; 1080 1171 if (irep->lv) { 1081 1172 for (i = 0; i + 1 < irep->nlocals; ++i) { 1082 1173 if (irep->lv[i].name) { 1083 mrb_ ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));1174 mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value()); 1084 1175 } 1085 1176 } … … 1090 1181 } 1091 1182 1092 return ret; 1093 } 1094 1183 return mrb_hash_keys(mrb, vars); 1184 } 1185 1186 mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); 1095 1187 void 1096 1188 mrb_init_kernel(mrb_state *mrb) … … 1108 1200 mrb_define_method(mrb, krn, "singleton_class", mrb_singleton_class, MRB_ARGS_NONE()); 1109 1201 1110 mrb_define_method(mrb, krn, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */1111 mrb_define_method(mrb, krn, "!=", mrb_obj_not_equal_m, MRB_ARGS_REQ(1));1112 1202 mrb_define_method(mrb, krn, "===", mrb_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */ 1113 mrb_define_method(mrb, krn, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.3 */1114 mrb_define_method(mrb, krn, "__send__", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.4 */1115 1203 mrb_define_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.6 */ 1116 1204 mrb_define_method(mrb, krn, "class", mrb_obj_class_m, MRB_ARGS_NONE()); /* 15.3.1.3.7 */ … … 1120 1208 mrb_define_method(mrb, krn, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */ 1121 1209 mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, MRB_ARGS_ANY()); /* 15.3.1.3.13 */ 1210 mrb_define_method(mrb, krn, "freeze", mrb_obj_freeze, MRB_ARGS_NONE()); 1211 mrb_define_method(mrb, krn, "frozen?", mrb_obj_frozen, MRB_ARGS_NONE()); 1122 1212 mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.3.14 */ 1123 1213 mrb_define_method(mrb, krn, "hash", mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */ 1124 1214 mrb_define_method(mrb, krn, "initialize_copy", mrb_obj_init_copy, MRB_ARGS_REQ(1)); /* 15.3.1.3.16 */ 1125 1215 mrb_define_method(mrb, krn, "inspect", mrb_obj_inspect, MRB_ARGS_NONE()); /* 15.3.1.3.17 */ 1126 mrb_define_method(mrb, krn, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_ANY()); /* 15.3.1.3.18 */1127 1216 mrb_define_method(mrb, krn, "instance_of?", obj_is_instance_of, MRB_ARGS_REQ(1)); /* 15.3.1.3.19 */ 1128 1217 mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined, MRB_ARGS_REQ(1)); /* 15.3.1.3.20 */ … … 1134 1223 mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.26 */ 1135 1224 mrb_define_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.3.28 */ 1225 #ifdef MRB_DEFAULT_METHOD_MISSING 1226 mrb_define_method(mrb, krn, "method_missing", mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */ 1227 #endif 1136 1228 mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.31 */ 1137 1229 mrb_define_method(mrb, krn, "nil?", mrb_false, MRB_ARGS_NONE()); /* 15.3.1.3.32 */
Note:
See TracChangeset
for help on using the changeset viewer.