mbed I/F binding for mruby

Dependents:   mruby_mbed_web mirb_mbed

mbed-mruby

How to use

Class

Committer:
mzta
Date:
Wed Mar 25 17:36:16 2015 +0000
Revision:
0:158c61bb030f
mirb_mbed initial commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mzta 0:158c61bb030f 1 /*
mzta 0:158c61bb030f 2 ** error.c - Exception class
mzta 0:158c61bb030f 3 **
mzta 0:158c61bb030f 4 ** See Copyright Notice in mruby.h
mzta 0:158c61bb030f 5 */
mzta 0:158c61bb030f 6
mzta 0:158c61bb030f 7 #include <errno.h>
mzta 0:158c61bb030f 8 #include <stdarg.h>
mzta 0:158c61bb030f 9 #include <stdlib.h>
mzta 0:158c61bb030f 10 #include "mruby.h"
mzta 0:158c61bb030f 11 #include "mruby/array.h"
mzta 0:158c61bb030f 12 #include "mruby/irep.h"
mzta 0:158c61bb030f 13 #include "mruby/proc.h"
mzta 0:158c61bb030f 14 #include "mruby/string.h"
mzta 0:158c61bb030f 15 #include "mruby/variable.h"
mzta 0:158c61bb030f 16 #include "mruby/debug.h"
mzta 0:158c61bb030f 17 #include "mruby/error.h"
mzta 0:158c61bb030f 18 #include "mruby/class.h"
mzta 0:158c61bb030f 19 #include "mrb_throw.h"
mzta 0:158c61bb030f 20
mzta 0:158c61bb030f 21 MRB_API mrb_value
mzta 0:158c61bb030f 22 mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len)
mzta 0:158c61bb030f 23 {
mzta 0:158c61bb030f 24 mrb_value arg = mrb_str_new(mrb, ptr, len);
mzta 0:158c61bb030f 25 return mrb_obj_new(mrb, c, 1, &arg);
mzta 0:158c61bb030f 26 }
mzta 0:158c61bb030f 27
mzta 0:158c61bb030f 28 MRB_API mrb_value
mzta 0:158c61bb030f 29 mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str)
mzta 0:158c61bb030f 30 {
mzta 0:158c61bb030f 31 str = mrb_str_to_str(mrb, str);
mzta 0:158c61bb030f 32 return mrb_obj_new(mrb, c, 1, &str);
mzta 0:158c61bb030f 33 }
mzta 0:158c61bb030f 34
mzta 0:158c61bb030f 35 /*
mzta 0:158c61bb030f 36 * call-seq:
mzta 0:158c61bb030f 37 * Exception.new(msg = nil) -> exception
mzta 0:158c61bb030f 38 *
mzta 0:158c61bb030f 39 * Construct a new Exception object, optionally passing in
mzta 0:158c61bb030f 40 * a message.
mzta 0:158c61bb030f 41 */
mzta 0:158c61bb030f 42
mzta 0:158c61bb030f 43 static mrb_value
mzta 0:158c61bb030f 44 exc_initialize(mrb_state *mrb, mrb_value exc)
mzta 0:158c61bb030f 45 {
mzta 0:158c61bb030f 46 mrb_value mesg;
mzta 0:158c61bb030f 47
mzta 0:158c61bb030f 48 if (mrb_get_args(mrb, "|o", &mesg) == 1) {
mzta 0:158c61bb030f 49 mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg);
mzta 0:158c61bb030f 50 }
mzta 0:158c61bb030f 51 return exc;
mzta 0:158c61bb030f 52 }
mzta 0:158c61bb030f 53
mzta 0:158c61bb030f 54 /*
mzta 0:158c61bb030f 55 * Document-method: exception
mzta 0:158c61bb030f 56 *
mzta 0:158c61bb030f 57 * call-seq:
mzta 0:158c61bb030f 58 * exc.exception(string) -> an_exception or exc
mzta 0:158c61bb030f 59 *
mzta 0:158c61bb030f 60 * With no argument, or if the argument is the same as the receiver,
mzta 0:158c61bb030f 61 * return the receiver. Otherwise, create a new
mzta 0:158c61bb030f 62 * exception object of the same class as the receiver, but with a
mzta 0:158c61bb030f 63 * message equal to <code>string.to_str</code>.
mzta 0:158c61bb030f 64 *
mzta 0:158c61bb030f 65 */
mzta 0:158c61bb030f 66
mzta 0:158c61bb030f 67 static mrb_value
mzta 0:158c61bb030f 68 exc_exception(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 69 {
mzta 0:158c61bb030f 70 mrb_value exc;
mzta 0:158c61bb030f 71 mrb_value a;
mzta 0:158c61bb030f 72 int argc;
mzta 0:158c61bb030f 73
mzta 0:158c61bb030f 74 argc = mrb_get_args(mrb, "|o", &a);
mzta 0:158c61bb030f 75 if (argc == 0) return self;
mzta 0:158c61bb030f 76 if (mrb_obj_equal(mrb, self, a)) return self;
mzta 0:158c61bb030f 77 exc = mrb_obj_clone(mrb, self);
mzta 0:158c61bb030f 78 mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), a);
mzta 0:158c61bb030f 79
mzta 0:158c61bb030f 80 return exc;
mzta 0:158c61bb030f 81 }
mzta 0:158c61bb030f 82
mzta 0:158c61bb030f 83 /*
mzta 0:158c61bb030f 84 * call-seq:
mzta 0:158c61bb030f 85 * exception.to_s -> string
mzta 0:158c61bb030f 86 *
mzta 0:158c61bb030f 87 * Returns exception's message (or the name of the exception if
mzta 0:158c61bb030f 88 * no message is set).
mzta 0:158c61bb030f 89 */
mzta 0:158c61bb030f 90
mzta 0:158c61bb030f 91 static mrb_value
mzta 0:158c61bb030f 92 exc_to_s(mrb_state *mrb, mrb_value exc)
mzta 0:158c61bb030f 93 {
mzta 0:158c61bb030f 94 mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
mzta 0:158c61bb030f 95 struct RObject *p;
mzta 0:158c61bb030f 96
mzta 0:158c61bb030f 97 if (!mrb_string_p(mesg)) {
mzta 0:158c61bb030f 98 return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc));
mzta 0:158c61bb030f 99 }
mzta 0:158c61bb030f 100 p = mrb_obj_ptr(mesg);
mzta 0:158c61bb030f 101 if (!p->c) {
mzta 0:158c61bb030f 102 p->c = mrb->string_class;
mzta 0:158c61bb030f 103 }
mzta 0:158c61bb030f 104 return mesg;
mzta 0:158c61bb030f 105 }
mzta 0:158c61bb030f 106
mzta 0:158c61bb030f 107 /*
mzta 0:158c61bb030f 108 * call-seq:
mzta 0:158c61bb030f 109 * exception.message -> string
mzta 0:158c61bb030f 110 *
mzta 0:158c61bb030f 111 * Returns the result of invoking <code>exception.to_s</code>.
mzta 0:158c61bb030f 112 * Normally this returns the exception's message or name. By
mzta 0:158c61bb030f 113 * supplying a to_str method, exceptions are agreeing to
mzta 0:158c61bb030f 114 * be used where Strings are expected.
mzta 0:158c61bb030f 115 */
mzta 0:158c61bb030f 116
mzta 0:158c61bb030f 117 static mrb_value
mzta 0:158c61bb030f 118 exc_message(mrb_state *mrb, mrb_value exc)
mzta 0:158c61bb030f 119 {
mzta 0:158c61bb030f 120 return mrb_funcall(mrb, exc, "to_s", 0);
mzta 0:158c61bb030f 121 }
mzta 0:158c61bb030f 122
mzta 0:158c61bb030f 123 /*
mzta 0:158c61bb030f 124 * call-seq:
mzta 0:158c61bb030f 125 * exception.inspect -> string
mzta 0:158c61bb030f 126 *
mzta 0:158c61bb030f 127 * Returns this exception's file name, line number,
mzta 0:158c61bb030f 128 * message and class name.
mzta 0:158c61bb030f 129 * If file name or line number is not set,
mzta 0:158c61bb030f 130 * returns message and class name.
mzta 0:158c61bb030f 131 */
mzta 0:158c61bb030f 132
mzta 0:158c61bb030f 133 static mrb_value
mzta 0:158c61bb030f 134 exc_inspect(mrb_state *mrb, mrb_value exc)
mzta 0:158c61bb030f 135 {
mzta 0:158c61bb030f 136 mrb_value str, mesg, file, line;
mzta 0:158c61bb030f 137 mrb_bool append_mesg;
mzta 0:158c61bb030f 138
mzta 0:158c61bb030f 139 mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
mzta 0:158c61bb030f 140 file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file"));
mzta 0:158c61bb030f 141 line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line"));
mzta 0:158c61bb030f 142
mzta 0:158c61bb030f 143 append_mesg = !mrb_nil_p(mesg);
mzta 0:158c61bb030f 144 if (append_mesg) {
mzta 0:158c61bb030f 145 mesg = mrb_obj_as_string(mrb, mesg);
mzta 0:158c61bb030f 146 append_mesg = RSTRING_LEN(mesg) > 0;
mzta 0:158c61bb030f 147 }
mzta 0:158c61bb030f 148
mzta 0:158c61bb030f 149 if (!mrb_nil_p(file) && !mrb_nil_p(line)) {
mzta 0:158c61bb030f 150 str = mrb_str_dup(mrb, file);
mzta 0:158c61bb030f 151 mrb_str_cat_lit(mrb, str, ":");
mzta 0:158c61bb030f 152 mrb_str_append(mrb, str, line);
mzta 0:158c61bb030f 153 mrb_str_cat_lit(mrb, str, ": ");
mzta 0:158c61bb030f 154 if (append_mesg) {
mzta 0:158c61bb030f 155 mrb_str_append(mrb, str, mesg);
mzta 0:158c61bb030f 156 mrb_str_cat_lit(mrb, str, " (");
mzta 0:158c61bb030f 157 }
mzta 0:158c61bb030f 158 mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
mzta 0:158c61bb030f 159 if (append_mesg) {
mzta 0:158c61bb030f 160 mrb_str_cat_lit(mrb, str, ")");
mzta 0:158c61bb030f 161 }
mzta 0:158c61bb030f 162 }
mzta 0:158c61bb030f 163 else {
mzta 0:158c61bb030f 164 const char *cname = mrb_obj_classname(mrb, exc);
mzta 0:158c61bb030f 165 str = mrb_str_new_cstr(mrb, cname);
mzta 0:158c61bb030f 166 mrb_str_cat_lit(mrb, str, ": ");
mzta 0:158c61bb030f 167 if (append_mesg) {
mzta 0:158c61bb030f 168 mrb_str_append(mrb, str, mesg);
mzta 0:158c61bb030f 169 }
mzta 0:158c61bb030f 170 else {
mzta 0:158c61bb030f 171 mrb_str_cat_cstr(mrb, str, cname);
mzta 0:158c61bb030f 172 }
mzta 0:158c61bb030f 173 }
mzta 0:158c61bb030f 174 return str;
mzta 0:158c61bb030f 175 }
mzta 0:158c61bb030f 176
mzta 0:158c61bb030f 177
mzta 0:158c61bb030f 178 static void
mzta 0:158c61bb030f 179 exc_debug_info(mrb_state *mrb, struct RObject *exc)
mzta 0:158c61bb030f 180 {
mzta 0:158c61bb030f 181 mrb_callinfo *ci = mrb->c->ci;
mzta 0:158c61bb030f 182 mrb_code *pc = ci->pc;
mzta 0:158c61bb030f 183
mzta 0:158c61bb030f 184 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value((mrb_int)(ci - mrb->c->cibase)));
mzta 0:158c61bb030f 185 while (ci >= mrb->c->cibase) {
mzta 0:158c61bb030f 186 mrb_code *err = ci->err;
mzta 0:158c61bb030f 187
mzta 0:158c61bb030f 188 if (!err && pc) err = pc - 1;
mzta 0:158c61bb030f 189 if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
mzta 0:158c61bb030f 190 mrb_irep *irep = ci->proc->body.irep;
mzta 0:158c61bb030f 191
mzta 0:158c61bb030f 192 int32_t const line = mrb_debug_get_line(irep, (uint32_t)(err - irep->iseq));
mzta 0:158c61bb030f 193 char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq));
mzta 0:158c61bb030f 194 if (line != -1 && file) {
mzta 0:158c61bb030f 195 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));
mzta 0:158c61bb030f 196 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));
mzta 0:158c61bb030f 197 return;
mzta 0:158c61bb030f 198 }
mzta 0:158c61bb030f 199 }
mzta 0:158c61bb030f 200 pc = ci->pc;
mzta 0:158c61bb030f 201 ci--;
mzta 0:158c61bb030f 202 }
mzta 0:158c61bb030f 203 }
mzta 0:158c61bb030f 204
mzta 0:158c61bb030f 205 MRB_API mrb_noreturn void
mzta 0:158c61bb030f 206 mrb_exc_raise(mrb_state *mrb, mrb_value exc)
mzta 0:158c61bb030f 207 {
mzta 0:158c61bb030f 208 mrb->exc = mrb_obj_ptr(exc);
mzta 0:158c61bb030f 209 if (!mrb->out_of_memory) {
mzta 0:158c61bb030f 210 exc_debug_info(mrb, mrb->exc);
mzta 0:158c61bb030f 211 }
mzta 0:158c61bb030f 212 if (!mrb->jmp) {
mzta 0:158c61bb030f 213 mrb_p(mrb, exc);
mzta 0:158c61bb030f 214 abort();
mzta 0:158c61bb030f 215 }
mzta 0:158c61bb030f 216 MRB_THROW(mrb->jmp);
mzta 0:158c61bb030f 217 }
mzta 0:158c61bb030f 218
mzta 0:158c61bb030f 219 MRB_API mrb_noreturn void
mzta 0:158c61bb030f 220 mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
mzta 0:158c61bb030f 221 {
mzta 0:158c61bb030f 222 mrb_value mesg;
mzta 0:158c61bb030f 223 mesg = mrb_str_new_cstr(mrb, msg);
mzta 0:158c61bb030f 224 mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg));
mzta 0:158c61bb030f 225 }
mzta 0:158c61bb030f 226
mzta 0:158c61bb030f 227 MRB_API mrb_value
mzta 0:158c61bb030f 228 mrb_vformat(mrb_state *mrb, const char *format, va_list ap)
mzta 0:158c61bb030f 229 {
mzta 0:158c61bb030f 230 const char *p = format;
mzta 0:158c61bb030f 231 const char *b = p;
mzta 0:158c61bb030f 232 ptrdiff_t size;
mzta 0:158c61bb030f 233 mrb_value ary = mrb_ary_new_capa(mrb, 4);
mzta 0:158c61bb030f 234
mzta 0:158c61bb030f 235 while (*p) {
mzta 0:158c61bb030f 236 const char c = *p++;
mzta 0:158c61bb030f 237
mzta 0:158c61bb030f 238 if (c == '%') {
mzta 0:158c61bb030f 239 if (*p == 'S') {
mzta 0:158c61bb030f 240 size = p - b - 1;
mzta 0:158c61bb030f 241 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
mzta 0:158c61bb030f 242 mrb_ary_push(mrb, ary, va_arg(ap, mrb_value));
mzta 0:158c61bb030f 243 b = p + 1;
mzta 0:158c61bb030f 244 }
mzta 0:158c61bb030f 245 }
mzta 0:158c61bb030f 246 else if (c == '\\') {
mzta 0:158c61bb030f 247 if (*p) {
mzta 0:158c61bb030f 248 size = p - b - 1;
mzta 0:158c61bb030f 249 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
mzta 0:158c61bb030f 250 mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1));
mzta 0:158c61bb030f 251 b = ++p;
mzta 0:158c61bb030f 252 }
mzta 0:158c61bb030f 253 else {
mzta 0:158c61bb030f 254 break;
mzta 0:158c61bb030f 255 }
mzta 0:158c61bb030f 256 }
mzta 0:158c61bb030f 257 }
mzta 0:158c61bb030f 258 if (b == format) {
mzta 0:158c61bb030f 259 return mrb_str_new_cstr(mrb, format);
mzta 0:158c61bb030f 260 }
mzta 0:158c61bb030f 261 else {
mzta 0:158c61bb030f 262 size = p - b;
mzta 0:158c61bb030f 263 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
mzta 0:158c61bb030f 264 return mrb_ary_join(mrb, ary, mrb_str_new(mrb, NULL, 0));
mzta 0:158c61bb030f 265 }
mzta 0:158c61bb030f 266 }
mzta 0:158c61bb030f 267
mzta 0:158c61bb030f 268 MRB_API mrb_value
mzta 0:158c61bb030f 269 mrb_format(mrb_state *mrb, const char *format, ...)
mzta 0:158c61bb030f 270 {
mzta 0:158c61bb030f 271 va_list ap;
mzta 0:158c61bb030f 272 mrb_value str;
mzta 0:158c61bb030f 273
mzta 0:158c61bb030f 274 va_start(ap, format);
mzta 0:158c61bb030f 275 str = mrb_vformat(mrb, format, ap);
mzta 0:158c61bb030f 276 va_end(ap);
mzta 0:158c61bb030f 277
mzta 0:158c61bb030f 278 return str;
mzta 0:158c61bb030f 279 }
mzta 0:158c61bb030f 280
mzta 0:158c61bb030f 281 MRB_API mrb_noreturn void
mzta 0:158c61bb030f 282 mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
mzta 0:158c61bb030f 283 {
mzta 0:158c61bb030f 284 va_list args;
mzta 0:158c61bb030f 285 mrb_value mesg;
mzta 0:158c61bb030f 286
mzta 0:158c61bb030f 287 va_start(args, fmt);
mzta 0:158c61bb030f 288 mesg = mrb_vformat(mrb, fmt, args);
mzta 0:158c61bb030f 289 va_end(args);
mzta 0:158c61bb030f 290 mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg));
mzta 0:158c61bb030f 291 }
mzta 0:158c61bb030f 292
mzta 0:158c61bb030f 293 MRB_API mrb_noreturn void
mzta 0:158c61bb030f 294 mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
mzta 0:158c61bb030f 295 {
mzta 0:158c61bb030f 296 mrb_value exc;
mzta 0:158c61bb030f 297 mrb_value argv[2];
mzta 0:158c61bb030f 298 va_list args;
mzta 0:158c61bb030f 299
mzta 0:158c61bb030f 300 va_start(args, fmt);
mzta 0:158c61bb030f 301 argv[0] = mrb_vformat(mrb, fmt, args);
mzta 0:158c61bb030f 302 va_end(args);
mzta 0:158c61bb030f 303
mzta 0:158c61bb030f 304 argv[1] = mrb_symbol_value(id);
mzta 0:158c61bb030f 305 exc = mrb_obj_new(mrb, E_NAME_ERROR, 2, argv);
mzta 0:158c61bb030f 306 mrb_exc_raise(mrb, exc);
mzta 0:158c61bb030f 307 }
mzta 0:158c61bb030f 308
mzta 0:158c61bb030f 309 MRB_API void
mzta 0:158c61bb030f 310 mrb_warn(mrb_state *mrb, const char *fmt, ...)
mzta 0:158c61bb030f 311 {
mzta 0:158c61bb030f 312 #ifdef ENABLE_STDIO
mzta 0:158c61bb030f 313 va_list ap;
mzta 0:158c61bb030f 314 mrb_value str;
mzta 0:158c61bb030f 315
mzta 0:158c61bb030f 316 va_start(ap, fmt);
mzta 0:158c61bb030f 317 str = mrb_vformat(mrb, fmt, ap);
mzta 0:158c61bb030f 318 fputs("warning: ", stderr);
mzta 0:158c61bb030f 319 fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr);
mzta 0:158c61bb030f 320 va_end(ap);
mzta 0:158c61bb030f 321 #endif
mzta 0:158c61bb030f 322 }
mzta 0:158c61bb030f 323
mzta 0:158c61bb030f 324 MRB_API mrb_noreturn void
mzta 0:158c61bb030f 325 mrb_bug(mrb_state *mrb, const char *fmt, ...)
mzta 0:158c61bb030f 326 {
mzta 0:158c61bb030f 327 #ifdef ENABLE_STDIO
mzta 0:158c61bb030f 328 va_list ap;
mzta 0:158c61bb030f 329 mrb_value str;
mzta 0:158c61bb030f 330
mzta 0:158c61bb030f 331 va_start(ap, fmt);
mzta 0:158c61bb030f 332 str = mrb_vformat(mrb, fmt, ap);
mzta 0:158c61bb030f 333 fputs("bug: ", stderr);
mzta 0:158c61bb030f 334 fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr);
mzta 0:158c61bb030f 335 va_end(ap);
mzta 0:158c61bb030f 336 #endif
mzta 0:158c61bb030f 337 exit(EXIT_FAILURE);
mzta 0:158c61bb030f 338 }
mzta 0:158c61bb030f 339
mzta 0:158c61bb030f 340 static void
mzta 0:158c61bb030f 341 set_backtrace(mrb_state *mrb, mrb_value info, mrb_value bt)
mzta 0:158c61bb030f 342 {
mzta 0:158c61bb030f 343 mrb_funcall(mrb, info, "set_backtrace", 1, bt);
mzta 0:158c61bb030f 344 }
mzta 0:158c61bb030f 345
mzta 0:158c61bb030f 346 static mrb_value
mzta 0:158c61bb030f 347 make_exception(mrb_state *mrb, int argc, const mrb_value *argv, mrb_bool isstr)
mzta 0:158c61bb030f 348 {
mzta 0:158c61bb030f 349 mrb_value mesg;
mzta 0:158c61bb030f 350 int n;
mzta 0:158c61bb030f 351
mzta 0:158c61bb030f 352 mesg = mrb_nil_value();
mzta 0:158c61bb030f 353 switch (argc) {
mzta 0:158c61bb030f 354 case 0:
mzta 0:158c61bb030f 355 break;
mzta 0:158c61bb030f 356 case 1:
mzta 0:158c61bb030f 357 if (mrb_nil_p(argv[0]))
mzta 0:158c61bb030f 358 break;
mzta 0:158c61bb030f 359 if (isstr) {
mzta 0:158c61bb030f 360 mesg = mrb_check_string_type(mrb, argv[0]);
mzta 0:158c61bb030f 361 if (!mrb_nil_p(mesg)) {
mzta 0:158c61bb030f 362 mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mesg);
mzta 0:158c61bb030f 363 break;
mzta 0:158c61bb030f 364 }
mzta 0:158c61bb030f 365 }
mzta 0:158c61bb030f 366 n = 0;
mzta 0:158c61bb030f 367 goto exception_call;
mzta 0:158c61bb030f 368
mzta 0:158c61bb030f 369 case 2:
mzta 0:158c61bb030f 370 case 3:
mzta 0:158c61bb030f 371 n = 1;
mzta 0:158c61bb030f 372 exception_call:
mzta 0:158c61bb030f 373 {
mzta 0:158c61bb030f 374 mrb_sym exc = mrb_intern_lit(mrb, "exception");
mzta 0:158c61bb030f 375 if (mrb_respond_to(mrb, argv[0], exc)) {
mzta 0:158c61bb030f 376 mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
mzta 0:158c61bb030f 377 }
mzta 0:158c61bb030f 378 else {
mzta 0:158c61bb030f 379 /* undef */
mzta 0:158c61bb030f 380 mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
mzta 0:158c61bb030f 381 }
mzta 0:158c61bb030f 382 }
mzta 0:158c61bb030f 383
mzta 0:158c61bb030f 384 break;
mzta 0:158c61bb030f 385 default:
mzta 0:158c61bb030f 386 mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc));
mzta 0:158c61bb030f 387 break;
mzta 0:158c61bb030f 388 }
mzta 0:158c61bb030f 389 if (argc > 0) {
mzta 0:158c61bb030f 390 if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class))
mzta 0:158c61bb030f 391 mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
mzta 0:158c61bb030f 392 if (argc > 2)
mzta 0:158c61bb030f 393 set_backtrace(mrb, mesg, argv[2]);
mzta 0:158c61bb030f 394 }
mzta 0:158c61bb030f 395
mzta 0:158c61bb030f 396 return mesg;
mzta 0:158c61bb030f 397 }
mzta 0:158c61bb030f 398
mzta 0:158c61bb030f 399 MRB_API mrb_value
mzta 0:158c61bb030f 400 mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)
mzta 0:158c61bb030f 401 {
mzta 0:158c61bb030f 402 return make_exception(mrb, argc, argv, TRUE);
mzta 0:158c61bb030f 403 }
mzta 0:158c61bb030f 404
mzta 0:158c61bb030f 405 MRB_API void
mzta 0:158c61bb030f 406 mrb_sys_fail(mrb_state *mrb, const char *mesg)
mzta 0:158c61bb030f 407 {
mzta 0:158c61bb030f 408 struct RClass *sce;
mzta 0:158c61bb030f 409 mrb_int no;
mzta 0:158c61bb030f 410
mzta 0:158c61bb030f 411 no = (mrb_int)errno;
mzta 0:158c61bb030f 412 if (mrb_class_defined(mrb, "SystemCallError")) {
mzta 0:158c61bb030f 413 sce = mrb_class_get(mrb, "SystemCallError");
mzta 0:158c61bb030f 414 if (mesg != NULL) {
mzta 0:158c61bb030f 415 mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
mzta 0:158c61bb030f 416 }
mzta 0:158c61bb030f 417 else {
mzta 0:158c61bb030f 418 mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
mzta 0:158c61bb030f 419 }
mzta 0:158c61bb030f 420 }
mzta 0:158c61bb030f 421 else {
mzta 0:158c61bb030f 422 mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
mzta 0:158c61bb030f 423 }
mzta 0:158c61bb030f 424 }
mzta 0:158c61bb030f 425
mzta 0:158c61bb030f 426 MRB_API mrb_noreturn void
mzta 0:158c61bb030f 427 mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, char const* fmt, ...)
mzta 0:158c61bb030f 428 {
mzta 0:158c61bb030f 429 mrb_value exc;
mzta 0:158c61bb030f 430 va_list ap;
mzta 0:158c61bb030f 431
mzta 0:158c61bb030f 432 va_start(ap, fmt);
mzta 0:158c61bb030f 433 exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3,
mzta 0:158c61bb030f 434 mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id),
mzta 0:158c61bb030f 435 mrb_ary_new_from_values(mrb, argc, argv));
mzta 0:158c61bb030f 436 va_end(ap);
mzta 0:158c61bb030f 437 mrb_exc_raise(mrb, exc);
mzta 0:158c61bb030f 438 }
mzta 0:158c61bb030f 439
mzta 0:158c61bb030f 440 void
mzta 0:158c61bb030f 441 mrb_init_exception(mrb_state *mrb)
mzta 0:158c61bb030f 442 {
mzta 0:158c61bb030f 443 struct RClass *exception, *runtime_error, *script_error;
mzta 0:158c61bb030f 444
mzta 0:158c61bb030f 445 mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
mzta 0:158c61bb030f 446 MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION);
mzta 0:158c61bb030f 447 mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_ANY());
mzta 0:158c61bb030f 448 mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_ANY());
mzta 0:158c61bb030f 449 mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_ANY());
mzta 0:158c61bb030f 450 mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE());
mzta 0:158c61bb030f 451 mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE());
mzta 0:158c61bb030f 452 mrb_define_method(mrb, exception, "inspect", exc_inspect, MRB_ARGS_NONE());
mzta 0:158c61bb030f 453 mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE());
mzta 0:158c61bb030f 454
mzta 0:158c61bb030f 455 mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
mzta 0:158c61bb030f 456 runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
mzta 0:158c61bb030f 457 mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str(mrb, runtime_error, mrb_str_new_lit(mrb, "Out of memory")));
mzta 0:158c61bb030f 458 script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */
mzta 0:158c61bb030f 459 mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */
mzta 0:158c61bb030f 460 mrb_define_class(mrb, "SystemStackError", exception);
mzta 0:158c61bb030f 461 }
mzta 0:158c61bb030f 462