Changeset 439 for EcnlProtoTool/trunk/mruby-2.1.1/src/error.c
- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/src/error.c
r331 r439 14 14 #include <mruby/string.h> 15 15 #include <mruby/variable.h> 16 #include <mruby/debug.h>17 16 #include <mruby/error.h> 18 17 #include <mruby/class.h> … … 29 28 mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) 30 29 { 31 str = mrb_str_to_str(mrb, str);30 mrb_to_str(mrb, str); 32 31 return mrb_obj_new(mrb, c, 1, &str); 33 32 } … … 45 44 { 46 45 mrb_value mesg; 47 mrb_int argc; 48 mrb_value *argv; 49 50 if (mrb_get_args(mrb, "|o*", &mesg, &argv, &argc) >= 1) { 46 47 if (mrb_get_args(mrb, "|o", &mesg) == 1) { 51 48 mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg); 52 49 } … … 72 69 mrb_value exc; 73 70 mrb_value a; 74 int argc;71 mrb_int argc; 75 72 76 73 argc = mrb_get_args(mrb, "|o", &a); … … 91 88 */ 92 89 93 staticmrb_value90 mrb_value 94 91 exc_to_s(mrb_state *mrb, mrb_value exc) 95 92 { … … 131 128 */ 132 129 133 static mrb_value 134 exc_inspect(mrb_state *mrb, mrb_value exc) 135 { 136 mrb_value str, mesg, file, line; 137 mrb_bool append_mesg; 138 const char *cname; 139 140 mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); 141 file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); 142 line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line")); 143 144 append_mesg = !mrb_nil_p(mesg); 145 if (append_mesg) { 146 mesg = mrb_obj_as_string(mrb, mesg); 147 append_mesg = RSTRING_LEN(mesg) > 0; 148 } 149 150 cname = mrb_obj_classname(mrb, exc); 151 str = mrb_str_new_cstr(mrb, cname); 152 if (mrb_string_p(file) && mrb_fixnum_p(line)) { 153 if (append_mesg) { 154 str = mrb_format(mrb, "%S:%S:%S (%S)", file, line, mesg, str); 155 } 156 else { 157 str = mrb_format(mrb, "%S:%S:%S", file, line, str); 158 } 159 } 160 else if (append_mesg) { 161 str = mrb_format(mrb, "%S:%S", str, mesg); 162 } 163 return str; 130 mrb_value 131 mrb_exc_inspect(mrb_state *mrb, mrb_value exc) 132 { 133 mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); 134 mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc))); 135 mesg = mrb_obj_as_string(mrb, mesg); 136 return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); 164 137 } 165 138 … … 195 168 } 196 169 197 static void198 exc_debug_info(mrb_state *mrb, struct RObject *exc)199 {200 mrb_callinfo *ci = mrb->c->ci;201 mrb_code *pc = ci->pc;202 203 while (ci >= mrb->c->cibase) {204 mrb_code *err = ci->err;205 206 if (!err && pc) err = pc - 1;207 if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {208 mrb_irep *irep = ci->proc->body.irep;209 210 int32_t const line = mrb_debug_get_line(irep, (uint32_t)(err - irep->iseq));211 char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq));212 if (line != -1 && file) {213 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));214 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));215 return;216 }217 }218 pc = ci->pc;219 ci--;220 }221 }222 223 170 void 224 171 mrb_exc_set(mrb_state *mrb, mrb_value exc) … … 229 176 else { 230 177 mrb->exc = mrb_obj_ptr(exc); 231 if (!mrb->gc.out_of_memory) { 232 exc_debug_info(mrb, mrb->exc); 178 if (mrb->gc.arena_idx > 0 && 179 (struct RBasic*)mrb->exc == mrb->gc.arena[mrb->gc.arena_idx-1]) { 180 mrb->gc.arena_idx--; 181 } 182 if (!mrb->gc.out_of_memory && !mrb_frozen_p(mrb->exc)) { 233 183 mrb_keep_backtrace(mrb, exc); 234 184 } … … 239 189 mrb_exc_raise(mrb_state *mrb, mrb_value exc) 240 190 { 241 if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { 242 mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); 243 } 244 mrb_exc_set(mrb, exc); 191 if (mrb_break_p(exc)) { 192 mrb->exc = mrb_obj_ptr(exc); 193 } 194 else { 195 if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { 196 mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); 197 } 198 mrb_exc_set(mrb, exc); 199 } 245 200 if (!mrb->jmp) { 246 201 mrb_p(mrb, exc); … … 256 211 } 257 212 213 /* 214 * <code>vsprintf</code> like formatting. 215 * 216 * The syntax of a format sequence is as follows. 217 * 218 * %[modifier]specifier 219 * 220 * The modifiers are: 221 * 222 * ----------+------------------------------------------------------------ 223 * Modifier | Meaning 224 * ----------+------------------------------------------------------------ 225 * ! | Convert to string by corresponding `inspect` instead of 226 * | corresponding `to_s`. 227 * ----------+------------------------------------------------------------ 228 * 229 * The specifiers are: 230 * 231 * ----------+----------------+-------------------------------------------- 232 * Specifier | Argument Type | Note 233 * ----------+----------------+-------------------------------------------- 234 * c | char | 235 * d | int | 236 * f | mrb_float | 237 * i | mrb_int | 238 * l | char*, size_t | Arguments are string and length. 239 * n | mrb_sym | 240 * s | char* | Argument is NUL terminated string. 241 * t | mrb_value | Convert to type (class) of object. 242 * v,S | mrb_value | 243 * C | struct RClass* | 244 * T | mrb_value | Convert to real type (class) of object. 245 * Y | mrb_value | Same as `!v` if argument is `true`, `false` 246 * | | or `nil`, otherwise same as `T`. 247 * % | - | Convert to percent sign itself (no argument 248 * | | taken). 249 * ----------+----------------+-------------------------------------------- 250 */ 258 251 MRB_API mrb_value 259 252 mrb_vformat(mrb_state *mrb, const char *format, va_list ap) 260 253 { 261 const char *p = format; 262 const char *b = p; 263 ptrdiff_t size; 264 mrb_value ary = mrb_ary_new_capa(mrb, 4); 254 const char *chars, *p = format, *b = format, *e; 255 char ch; 256 size_t len; 257 mrb_int i; 258 struct RClass *cls; 259 mrb_bool inspect = FALSE; 260 mrb_value result = mrb_str_new_capa(mrb, 128), obj, str; 265 261 int ai = mrb_gc_arena_save(mrb); 266 262 267 263 while (*p) { 268 264 const char c = *p++; 269 265 e = p; 270 266 if (c == '%') { 271 if (*p == 'S') { 272 size = p - b - 1; 273 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); 274 mrb_ary_push(mrb, ary, va_arg(ap, mrb_value)); 275 b = p + 1; 267 if (*p == '!') { 268 inspect = TRUE; 269 ++p; 276 270 } 271 if (!*p) break; 272 switch (*p) { 273 case 'c': 274 ch = (char)va_arg(ap, int); 275 chars = &ch; 276 len = 1; 277 goto L_cat; 278 case 'd': case 'i': 279 #if MRB_INT_MAX < INT_MAX 280 i = (mrb_int)va_arg(ap, int); 281 #else 282 i = *p == 'd' ? (mrb_int)va_arg(ap, int) : va_arg(ap, mrb_int); 283 #endif 284 obj = mrb_fixnum_value(i); 285 goto L_cat_obj; 286 #ifndef MRB_WITHOUT_FLOAT 287 case 'f': 288 obj = mrb_float_value(mrb, (mrb_float)va_arg(ap, double)); 289 goto L_cat_obj; 290 #endif 291 case 'l': 292 chars = va_arg(ap, char*); 293 len = va_arg(ap, size_t); 294 L_cat: 295 if (inspect) { 296 obj = mrb_str_new(mrb, chars, len); 297 goto L_cat_obj; 298 } 299 mrb_str_cat(mrb, result, b, e - b - 1); 300 mrb_str_cat(mrb, result, chars, len); 301 b = ++p; 302 mrb_gc_arena_restore(mrb, ai); 303 break; 304 case 'n': 305 #if UINT32_MAX < INT_MAX 306 obj = mrb_symbol_value((mrb_sym)va_arg(ap, int)); 307 #else 308 obj = mrb_symbol_value(va_arg(ap, mrb_sym)); 309 #endif 310 goto L_cat_obj; 311 case 's': 312 chars = va_arg(ap, char*); 313 len = strlen(chars); 314 goto L_cat; 315 case 't': 316 cls = mrb_class(mrb, va_arg(ap, mrb_value)); 317 goto L_cat_class; 318 case 'v': case 'S': 319 obj = va_arg(ap, mrb_value); 320 L_cat_obj: 321 str = (inspect ? mrb_inspect : mrb_obj_as_string)(mrb, obj); 322 chars = RSTRING_PTR(str); 323 len = RSTRING_LEN(str); 324 inspect = FALSE; 325 goto L_cat; 326 case 'C': 327 cls = va_arg(ap, struct RClass*); 328 L_cat_class: 329 obj = mrb_obj_value(cls); 330 goto L_cat_obj; 331 case 'T': 332 obj = va_arg(ap, mrb_value); 333 L_cat_real_class_of: 334 cls = mrb_obj_class(mrb, obj); 335 goto L_cat_class; 336 case 'Y': 337 obj = va_arg(ap, mrb_value); 338 if (!mrb_test(obj) || mrb_true_p(obj)) { 339 inspect = TRUE; 340 goto L_cat_obj; 341 } 342 else { 343 goto L_cat_real_class_of; 344 } 345 case '%': 346 L_cat_current: 347 chars = p; 348 len = 1; 349 goto L_cat; 350 default: 351 mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); 352 } 277 353 } 278 354 else if (c == '\\') { 279 if (*p) { 280 size = p - b - 1; 281 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); 282 mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1)); 283 b = ++p; 284 } 285 else { 286 break; 287 } 288 } 289 mrb_gc_arena_restore(mrb, ai); 290 } 291 if (b == format) { 292 return mrb_str_new_cstr(mrb, format); 293 } 294 else { 295 size = p - b; 296 if (size > 0) { 297 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); 298 mrb_gc_arena_restore(mrb, ai); 299 } 300 return mrb_ary_join(mrb, ary, mrb_nil_value()); 301 } 355 if (!*p) break; 356 goto L_cat_current; 357 358 } 359 } 360 361 mrb_str_cat(mrb, result, b, p - b); 362 return result; 302 363 } 303 364 … … 319 380 { 320 381 mrb_value mesg; 382 static int called = 0; 321 383 322 384 mesg = mrb_vformat(mrb, fmt, ap); … … 327 389 argv[0] = mesg; 328 390 } 391 if (called) 392 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); 393 called = 1; 329 394 mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv)); 330 395 } … … 363 428 fputs("warning: ", stderr); 364 429 fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); 430 putc('\n', stderr); 365 431 va_end(ap); 366 432 #endif … … 384 450 385 451 MRB_API mrb_value 386 mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)452 mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv) 387 453 { 388 454 mrb_value mesg; … … 420 486 break; 421 487 default: 422 mrb_ raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc));488 mrb_argnum_error(mrb, argc, 0, 3); 423 489 break; 424 490 } … … 470 536 } 471 537 538 MRB_API mrb_noreturn void 539 mrb_frozen_error(mrb_state *mrb, void *frozen_obj) 540 { 541 mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj)); 542 } 543 544 MRB_API mrb_noreturn void 545 mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max) 546 { 547 #define FMT(exp) "wrong number of arguments (given %i, expected " exp ")" 548 if (min == max) 549 mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d"), argc, min); 550 else if (max < 0) 551 mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d+"), argc, min); 552 else 553 mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d..%d"), argc, min, max); 554 #undef FMT 555 } 556 472 557 void 473 558 mrb_init_exception(mrb_state *mrb) … … 477 562 mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ 478 563 MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); 479 mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_ ANY());480 mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_ ANY());481 mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_ ANY());564 mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_OPT(1)); 565 mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_OPT(1)); 566 mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_OPT(1)); 482 567 mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE()); 483 568 mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE()); 484 mrb_define_method(mrb, exception, "inspect", exc_inspect,MRB_ARGS_NONE());569 mrb_define_method(mrb, exception, "inspect", mrb_exc_inspect, MRB_ARGS_NONE()); 485 570 mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE()); 486 571 mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1));
Note:
See TracChangeset
for help on using the changeset viewer.