Changeset 331 for EcnlProtoTool/trunk/mruby-1.3.0/src/error.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/error.c
r321 r331 8 8 #include <stdarg.h> 9 9 #include <stdlib.h> 10 #include "mruby.h"11 #include "mruby/array.h"12 #include "mruby/irep.h"13 #include "mruby/proc.h"14 #include "mruby/string.h"15 #include "mruby/variable.h"16 #include "mruby/debug.h"17 #include "mruby/error.h"18 #include "mruby/class.h"19 #include "mruby/throw.h"10 #include <mruby.h> 11 #include <mruby/array.h> 12 #include <mruby/irep.h> 13 #include <mruby/proc.h> 14 #include <mruby/string.h> 15 #include <mruby/variable.h> 16 #include <mruby/debug.h> 17 #include <mruby/error.h> 18 #include <mruby/class.h> 19 #include <mruby/throw.h> 20 20 21 21 MRB_API mrb_value … … 45 45 { 46 46 mrb_value mesg; 47 48 if (mrb_get_args(mrb, "|o", &mesg) == 1) { 47 mrb_int argc; 48 mrb_value *argv; 49 50 if (mrb_get_args(mrb, "|o*", &mesg, &argv, &argc) >= 1) { 49 51 mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg); 50 52 } … … 61 63 * return the receiver. Otherwise, create a new 62 64 * exception object of the same class as the receiver, but with a 63 * message equal to <code>string .to_str</code>.65 * message equal to <code>string</code>. 64 66 * 65 67 */ … … 110 112 * 111 113 * Returns the result of invoking <code>exception.to_s</code>. 112 * Normally this returns the exception's message or name. By 113 * supplying a to_str method, exceptions are agreeing to 114 * be used where Strings are expected. 114 * Normally this returns the exception's message or name. 115 115 */ 116 116 … … 136 136 mrb_value str, mesg, file, line; 137 137 mrb_bool append_mesg; 138 const char *cname; 138 139 139 140 mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); … … 147 148 } 148 149 149 if (!mrb_nil_p(file) && !mrb_nil_p(line)) { 150 str = mrb_str_dup(mrb, file); 151 mrb_str_cat_lit(mrb, str, ":"); 152 mrb_str_append(mrb, str, line); 153 mrb_str_cat_lit(mrb, str, ": "); 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)) { 154 153 if (append_mesg) { 155 mrb_str_cat_str(mrb, str, mesg); 156 mrb_str_cat_lit(mrb, str, " ("); 157 } 158 mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); 159 if (append_mesg) { 160 mrb_str_cat_lit(mrb, str, ")"); 161 } 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; 164 } 165 166 void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc); 167 168 static void 169 set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace) 170 { 171 if (!mrb_array_p(backtrace)) { 172 type_err: 173 mrb_raise(mrb, E_TYPE_ERROR, "backtrace must be Array of String"); 162 174 } 163 175 else { 164 const char *cname = mrb_obj_classname(mrb, exc); 165 str = mrb_str_new_cstr(mrb, cname); 166 mrb_str_cat_lit(mrb, str, ": "); 167 if (append_mesg) { 168 mrb_str_cat_str(mrb, str, mesg); 169 } 170 else { 171 mrb_str_cat_cstr(mrb, str, cname); 172 } 173 } 174 return str; 175 } 176 176 const mrb_value *p = RARRAY_PTR(backtrace); 177 const mrb_value *pend = p + RARRAY_LEN(backtrace); 178 179 while (p < pend) { 180 if (!mrb_string_p(*p)) goto type_err; 181 p++; 182 } 183 } 184 mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace); 185 } 186 187 static mrb_value 188 exc_set_backtrace(mrb_state *mrb, mrb_value exc) 189 { 190 mrb_value backtrace; 191 192 mrb_get_args(mrb, "o", &backtrace); 193 set_backtrace(mrb, exc, backtrace); 194 return backtrace; 195 } 177 196 178 197 static void … … 182 201 mrb_code *pc = ci->pc; 183 202 184 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value((mrb_int)(ci - mrb->c->cibase)));185 203 while (ci >= mrb->c->cibase) { 186 204 mrb_code *err = ci->err; … … 203 221 } 204 222 223 void 224 mrb_exc_set(mrb_state *mrb, mrb_value exc) 225 { 226 if (mrb_nil_p(exc)) { 227 mrb->exc = 0; 228 } 229 else { 230 mrb->exc = mrb_obj_ptr(exc); 231 if (!mrb->gc.out_of_memory) { 232 exc_debug_info(mrb, mrb->exc); 233 mrb_keep_backtrace(mrb, exc); 234 } 235 } 236 } 237 205 238 MRB_API mrb_noreturn void 206 239 mrb_exc_raise(mrb_state *mrb, mrb_value exc) 207 240 { 208 mrb->exc = mrb_obj_ptr(exc);209 if (!mrb->gc.out_of_memory) {210 exc_debug_info(mrb, mrb->exc);211 }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); 212 245 if (!mrb->jmp) { 213 246 mrb_p(mrb, exc); … … 220 253 mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg) 221 254 { 222 mrb_value mesg; 223 mesg = mrb_str_new_cstr(mrb, msg); 224 mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg)); 255 mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mrb_str_new_cstr(mrb, msg))); 225 256 } 226 257 … … 232 263 ptrdiff_t size; 233 264 mrb_value ary = mrb_ary_new_capa(mrb, 4); 265 int ai = mrb_gc_arena_save(mrb); 234 266 235 267 while (*p) { … … 255 287 } 256 288 } 289 mrb_gc_arena_restore(mrb, ai); 257 290 } 258 291 if (b == format) { … … 261 294 else { 262 295 size = p - b; 263 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); 264 return mrb_ary_join(mrb, ary, mrb_str_new(mrb, NULL, 0)); 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()); 265 301 } 266 302 } … … 279 315 } 280 316 317 static mrb_noreturn void 318 raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list ap, int argc, mrb_value *argv) 319 { 320 mrb_value mesg; 321 322 mesg = mrb_vformat(mrb, fmt, ap); 323 if (argv == NULL) { 324 argv = &mesg; 325 } 326 else { 327 argv[0] = mesg; 328 } 329 mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv)); 330 } 331 281 332 MRB_API mrb_noreturn void 282 333 mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...) 283 334 { 284 335 va_list args; 285 mrb_value mesg;286 336 287 337 va_start(args, fmt); 288 mesg = mrb_vformat(mrb, fmt, args);338 raise_va(mrb, c, fmt, args, 0, NULL); 289 339 va_end(args); 290 mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg));291 340 } 292 341 … … 294 343 mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...) 295 344 { 296 mrb_value exc;297 345 mrb_value argv[2]; 298 346 va_list args; 299 347 300 348 va_start(args, fmt); 301 argv[0] = mrb_vformat(mrb, fmt, args); 349 argv[1] = mrb_symbol_value(id); 350 raise_va(mrb, E_NAME_ERROR, fmt, args, 1, argv); 302 351 va_end(args); 303 304 argv[1] = mrb_symbol_value(id);305 exc = mrb_obj_new(mrb, E_NAME_ERROR, 2, argv);306 mrb_exc_raise(mrb, exc);307 352 } 308 353 … … 338 383 } 339 384 340 static void 341 set_backtrace(mrb_state *mrb, mrb_value info, mrb_value bt) 342 { 343 mrb_funcall(mrb, info, "set_backtrace", 1, bt); 344 } 345 346 static mrb_value 347 make_exception(mrb_state *mrb, int argc, const mrb_value *argv, mrb_bool isstr) 385 MRB_API mrb_value 386 mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv) 348 387 { 349 388 mrb_value mesg; … … 357 396 if (mrb_nil_p(argv[0])) 358 397 break; 359 if (isstr) { 360 mesg = mrb_check_string_type(mrb, argv[0]); 361 if (!mrb_nil_p(mesg)) { 362 mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mesg); 363 break; 364 } 398 if (mrb_string_p(argv[0])) { 399 mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, argv[0]); 400 break; 365 401 } 366 402 n = 0; … … 389 425 if (argc > 0) { 390 426 if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) 391 mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");427 mrb_raise(mrb, mrb->eException_class, "exception object expected"); 392 428 if (argc > 2) 393 429 set_backtrace(mrb, mesg, argv[2]); 394 430 } 395 431 396 432 return mesg; 397 }398 399 MRB_API mrb_value400 mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)401 {402 return make_exception(mrb, argc, argv, TRUE);403 433 } 404 434 … … 428 458 { 429 459 mrb_value exc; 460 mrb_value argv[3]; 430 461 va_list ap; 431 462 432 463 va_start(ap, fmt); 433 exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3, 434 mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), args); 464 argv[0] = mrb_vformat(mrb, fmt, ap); 465 argv[1] = mrb_symbol_value(id); 466 argv[2] = args; 435 467 va_end(ap); 468 exc = mrb_obj_new(mrb, E_NOMETHOD_ERROR, 3, argv); 436 469 mrb_exc_raise(mrb, exc); 437 470 } … … 440 473 mrb_init_exception(mrb_state *mrb) 441 474 { 442 struct RClass *exception, * runtime_error, *script_error;475 struct RClass *exception, *script_error, *stack_error, *nomem_error; 443 476 444 477 mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ … … 451 484 mrb_define_method(mrb, exception, "inspect", exc_inspect, MRB_ARGS_NONE()); 452 485 mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE()); 486 mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); 453 487 454 488 mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ 455 runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ 456 mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "Out of memory")); 489 mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ 457 490 script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ 458 491 mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ 459 mrb_define_class(mrb, "SystemStackError", exception); 460 } 492 stack_error = mrb_define_class(mrb, "SystemStackError", exception); 493 mrb->stack_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, stack_error, "stack level too deep")); 494 495 nomem_error = mrb_define_class(mrb, "NoMemoryError", exception); 496 mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "Out of memory")); 497 #ifdef MRB_GC_FIXED_ARENA 498 mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "arena overflow error")); 499 #endif 500 }
Note:
See TracChangeset
for help on using the changeset viewer.