void mrb_exc_set(mrb_state *mrb, mrb_value exc) { if (!mrb->gc.out_of_memory && mrb->backtrace.n > 0) { mrb_value target_exc = mrb_nil_value(); if ((mrb->exc && !have_backtrace(mrb, mrb->exc))) { target_exc = mrb_obj_value(mrb->exc); } else if (!mrb_nil_p(exc) && mrb_obj_ptr(exc) == mrb->backtrace.exc) { target_exc = exc; } if (!mrb_nil_p(target_exc)) { mrb_value backtrace; backtrace = mrb_restore_backtrace(mrb); set_backtrace(mrb, target_exc, backtrace); } } mrb->backtrace.n = 0; if (mrb_nil_p(exc)) { mrb->exc = 0; } else { mrb->exc = mrb_obj_ptr(exc); } }
void mrb_init_exception(mrb_state *mrb) { struct RClass *exception, *runtime_error, *script_error; mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_ANY()); mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_ANY()); mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_ANY()); mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "inspect", exc_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "backtrace", exc_get_backtrace, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "Out of memory")); #ifdef MRB_GC_FIXED_ARENA mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "arena overflow error")); #endif script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ mrb_define_class(mrb, "SystemStackError", exception); }
void mrb_irep_free(mrb_state *mrb, mrb_irep *irep) { size_t i; if (!(irep->flags & MRB_ISEQ_NO_FREE)) mrb_free(mrb, irep->iseq); for (i=0; i<irep->plen; i++) { if (mrb_type(irep->pool[i]) == MRB_TT_STRING) { mrb_gc_free_str(mrb, RSTRING(irep->pool[i])); mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } #ifdef MRB_WORD_BOXING else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } #endif } mrb_free(mrb, irep->pool); mrb_free(mrb, irep->syms); for (i=0; i<irep->rlen; i++) { mrb_irep_decref(mrb, irep->reps[i]); } mrb_free(mrb, irep->reps); mrb_free(mrb, irep->lv); mrb_free(mrb, (void *)irep->filename); mrb_free(mrb, irep->lines); mrb_debug_info_free(mrb, irep->debug_info); mrb_free(mrb, irep); }
/* * call-seq: * obj.instance_variables -> array * * Returns an array of instance variable names for the receiver. Note * that simply defining an accessor does not create the corresponding * instance variable. * * class Fred * attr_accessor :a1 * def initialize * @iv = 3 * end * end * Fred.new.instance_variables #=> [:@iv] */ mrb_value mrb_obj_instance_variables(mrb_state *mrb, mrb_value self) { mrb_value ary; ary = mrb_ary_new(mrb); if (obj_iv_p(self) && mrb_obj_ptr(self)->iv) { iv_foreach(mrb, mrb_obj_ptr(self)->iv, iv_i, &ary); } return ary; }
/* * call-seq: * mod.class_variables -> array * * Returns an array of the names of class variables in <i>mod</i>. * * class One * @@var1 = 1 * end * class Two < One * @@var2 = 2 * end * One.class_variables #=> [:@@var1] * Two.class_variables #=> [:@@var2] */ mrb_value mrb_mod_class_variables(mrb_state *mrb, mrb_value mod) { mrb_value ary; ary = mrb_ary_new(mrb); if (obj_iv_p(mod) && mrb_obj_ptr(mod)->iv) { iv_foreach(mrb, mrb_obj_ptr(mod)->iv, cv_i, &ary); } return ary; }
void mrb_iv_copy(mrb_state *mrb, mrb_value dest, mrb_value src) { struct RObject *d = mrb_obj_ptr(dest); struct RObject *s = mrb_obj_ptr(src); if (d->iv) { iv_free(mrb, d->iv); d->iv = 0; } if (s->iv) { d->iv = iv_copy(mrb, s->iv); } }
MRB_API void mrb_iv_copy(mrb_state *mrb, mrb_value dest, mrb_value src) { struct RObject *d = mrb_obj_ptr(dest); struct RObject *s = mrb_obj_ptr(src); if (d->iv) { iv_free(mrb, d->iv); d->iv = 0; } if (s->iv) { mrb_write_barrier(mrb, (struct RBasic*)d); d->iv = iv_copy(mrb, s->iv); } }
static mrb_value cfunc_string_to_pointer(mrb_state *mrb, mrb_value self) { mrb_value ptr = cfunc_pointer_new_with_pointer(mrb, &RSTRING_PTR(self), false); mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern(mrb, "parent_pointer"), self); // keep for GC return ptr; }
static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) { if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) { struct RObject *c = mrb_obj_ptr(v); if (obj != c && ISUPPER(mrb_sym2name(mrb, sym)[0])) { mrb_sym id_classname = mrb_intern_lit(mrb, "__classname__"); mrb_value o = mrb_obj_iv_get(mrb, c, id_classname); if (mrb_nil_p(o)) { mrb_sym id_outer = mrb_intern_lit(mrb, "__outer__"); o = mrb_obj_iv_get(mrb, c, id_outer); if (mrb_nil_p(o)) { if ((struct RClass *)obj == mrb->object_class) { mrb_obj_iv_set(mrb, c, id_classname, mrb_symbol_value(sym)); } else { mrb_obj_iv_set(mrb, c, id_outer, mrb_obj_value(obj)); } } } } } }
void mrb_irep_free(MemManager &mm, mrb_irep *irep) { if (!(irep->flags & MRB_ISEQ_NO_FREE)) mm._free(irep->iseq); for (int i=0; i<irep->plen; i++) { if (mrb_type(irep->pool[i]) == MRB_TT_STRING) { if ((irep->pool[i].ptr<RString>()->flags & MRB_STR_NOFREE) == 0) { mm._free(irep->pool[i].ptr<RString>()->m_ptr); } mm._free(irep->pool[i].basic_ptr()); } #ifdef MRB_WORD_BOXING else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } #endif } mm._free(irep->pool); mm._free(irep->syms); for (int i=0; i<irep->rlen; i++) { mrb_irep_decref(mm, irep->reps[i]); } mm._free(irep->reps); mm._free((void *)irep->filename); mm._free(irep->lines); mrb_debug_info_free(mm, irep->debug_info); mm._free(irep); }
static mrb_value read_object(MarshalContext *ctx) { mrb_state *mrb = ctx->mrb; mrb_value class_path = read_value(ctx); struct RClass *klass = mrb_class_from_path(mrb, class_path); mrb_value obj = mrb_obj_value(mrb_obj_alloc(mrb, MRB_TT_OBJECT, klass)); ctx->objects.add(obj); int iv_count = read_fixnum(ctx); int i; for (i = 0; i < iv_count; ++i) { mrb_value iv_name = read_value(ctx); mrb_value iv_value = read_value(ctx); mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), mrb_symbol(iv_name), iv_value); } return obj; }
void mrb_exc_set(mrb_state *mrb, mrb_value exc) { if (!mrb->gc.out_of_memory && mrb->backtrace.n > 0) { mrb_value target_exc = mrb_nil_value(); int ai; ai = mrb_gc_arena_save(mrb); if ((mrb->exc && !have_backtrace(mrb, mrb->exc))) { target_exc = mrb_obj_value(mrb->exc); } else if (!mrb_nil_p(exc) && mrb->backtrace.exc) { target_exc = mrb_obj_value(mrb->backtrace.exc); mrb_gc_protect(mrb, target_exc); } if (!mrb_nil_p(target_exc)) { mrb_value backtrace; backtrace = mrb_restore_backtrace(mrb); set_backtrace(mrb, target_exc, backtrace); } mrb_gc_arena_restore(mrb, ai); } mrb->backtrace.n = 0; if (mrb_nil_p(exc)) { mrb->exc = 0; } else { if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); mrb->exc = mrb_obj_ptr(exc); } }
/* * call-seq: * raise * raise(string) * raise(exception [, string]) * * With no arguments, raises a <code>RuntimeError</code> * With a single +String+ argument, raises a * +RuntimeError+ with the string as a message. Otherwise, * the first parameter should be the name of an +Exception+ * class (or an object that returns an +Exception+ object when sent * an +exception+ message). The optional second parameter sets the * message associated with the exception, and the third parameter is an * array of callback information. Exceptions are caught by the * +rescue+ clause of <code>begin...end</code> blocks. * * raise "Failed to create socket" * raise ArgumentError, "No parameters", caller */ mrb_value mrb_f_raise(mrb_state *mrb, mrb_value self) { mrb_value a[2], exc; int argc; argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); switch (argc) { case 0: mrb_raise(mrb, E_RUNTIME_ERROR, ""); break; case 1: a[1] = mrb_check_string_type(mrb, a[0]); if (!mrb_nil_p(a[1])) { argc = 2; a[0] = mrb_obj_value(E_RUNTIME_ERROR); } /* fall through */ default: exc = mrb_make_exception(mrb, argc, a); mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_cptr_value(mrb, mrb->c->ci->pc)); mrb_exc_raise(mrb, exc); break; } return mrb_nil_value(); /* not reached */ }
grn_obj * grn_mrb_expr_rewrite(grn_ctx *ctx, grn_obj *expr) { grn_mrb_data *data = &(ctx->impl->mrb); mrb_state *mrb = data->state; mrb_value mrb_expression; mrb_value mrb_rewritten_expression; grn_obj *rewritten_expression = NULL; int arena_index; arena_index = mrb_gc_arena_save(mrb); mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr); mrb_rewritten_expression = mrb_funcall(mrb, mrb_expression, "rewrite", 0); if (mrb_nil_p(mrb_rewritten_expression)) { goto exit; } if (mrb_type(mrb_rewritten_expression) == MRB_TT_EXCEPTION) { mrb->exc = mrb_obj_ptr(mrb_rewritten_expression); mrb_print_error(mrb); goto exit; } rewritten_expression = DATA_PTR(mrb_rewritten_expression); exit: mrb_gc_arena_restore(mrb, arena_index); return rewritten_expression; }
mrb_value grn_mrb_load(grn_ctx *ctx, const char *path) { grn_mrb_data *data = &(ctx->impl->mrb); mrb_state *mrb = data->state; char expanded_path[PATH_MAX]; FILE *file; mrb_value result; struct mrb_parser_state *parser; if (!mrb) { return mrb_nil_value(); } if (!grn_mrb_expand_script_path(ctx, path, expanded_path, PATH_MAX)) { return mrb_nil_value(); } file = grn_fopen(expanded_path, "r"); if (!file) { mrb_value exception; SERR("fopen: failed to open mruby script file: <%s>", expanded_path); exception = mrb_exc_new(mrb, E_LOAD_ERROR, ctx->errbuf, strlen(ctx->errbuf)); mrb->exc = mrb_obj_ptr(exception); return mrb_nil_value(); } { char current_base_directory[PATH_MAX]; char *last_directory; grn_strcpy(current_base_directory, PATH_MAX, data->base_directory); grn_strcpy(data->base_directory, PATH_MAX, expanded_path); last_directory = strrchr(data->base_directory, '/'); if (last_directory) { last_directory[0] = '\0'; } parser = mrb_parser_new(mrb); mrb_parser_set_filename(parser, expanded_path); parser->s = parser->send = NULL; parser->f = file; mrb_parser_parse(parser, NULL); fclose(file); { struct RProc *proc; proc = mrb_generate_code(mrb, parser); result = mrb_toplevel_run(mrb, proc); } mrb_parser_free(parser); grn_strcpy(data->base_directory, PATH_MAX, current_base_directory); } return result; }
mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym) { if (obj_iv_p(obj)) { return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym); } return mrb_nil_value(); }
/* * call-seq: * obj.inspect -> string * * Returns a string containing a human-readable representation of * <i>obj</i>. If not overridden and no instance variables, uses the * <code>to_s</code> method to generate the string. * <i>obj</i>. If not overridden, uses the <code>to_s</code> method to * generate the string. * * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]" * Time.new.inspect #=> "2008-03-08 19:43:39 +0900" */ mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value obj) { if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) { return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); } return mrb_any_to_s(mrb, obj); }
void mrb_irep_free(mrb_state *mrb, mrb_irep *irep) { size_t i; if (!(irep->flags & MRB_ISEQ_NO_FREE)) mrb_free(mrb, irep->iseq); for (i=0; i<irep->plen; i++) { if (mrb_type(irep->pool[i]) == MRB_TT_STRING) { if ((mrb_str_ptr(irep->pool[i])->flags & (MRB_STR_NOFREE|MRB_STR_EMBED)) == 0) { mrb_free(mrb, RSTRING_PTR(irep->pool[i])); } mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } #ifdef MRB_WORD_BOXING else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } #endif } mrb_free(mrb, irep->pool); mrb_free(mrb, irep->syms); for (i=0; i<irep->rlen; i++) { mrb_irep_decref(mrb, irep->reps[i]); } mrb_free(mrb, irep->reps); mrb_free(mrb, (void *)irep->filename); mrb_free(mrb, irep->lines); mrb_free(mrb, irep->prof_info); if (irep->jit_entry_tab) { int i; int j; for (i = 0; i < irep->ilen; i++) { for (j = 0; j < irep->jit_entry_tab[i].size; j++) { if (irep->jit_entry_tab[i].body[j].reginfo) { mrb_free(mrb, irep->jit_entry_tab[i].body[j].reginfo); } } } mrb_free(mrb, irep->jit_entry_tab->body); mrb_free(mrb, irep->jit_entry_tab); } mrb_debug_info_free(mrb, irep->debug_info); mrb_free(mrb, irep); }
void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) { if (obj_iv_p(obj)) { mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), sym, v); } else { mrb_raise(mrb, E_ARGUMENT_ERROR, "cannot set instance variable"); } }
mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value self) { mrb_value ary; ary = mrb_ary_new(mrb); exc_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary)); return ary; }
void mrb_exc_raise(mrb_state *mrb, mrb_value exc) { mrb->exc = mrb_obj_ptr(exc); exc_debug_info(mrb, mrb->exc); if (!mrb->jmp) { mrb_p(mrb, exc); abort(); } longjmp(*(jmp_buf*)mrb->jmp, 1); }
/* * call-seq: * obj.instance_variable_defined?(symbol) -> true or false * * Returns <code>true</code> if the given instance variable is * defined in <i>obj</i>. * * class Fred * def initialize(p1, p2) * @a, @b = p1, p2 * end * end * fred = Fred.new('cat', 99) * fred.instance_variable_defined?(:@a) #=> true * fred.instance_variable_defined?("@b") #=> true * fred.instance_variable_defined?("@c") #=> false */ mrb_value mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) { mrb_sym mid; mrb_get_args(mrb, "n", &mid); check_iv_name(mrb, mid); if (mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid)) return mrb_true_value(); return mrb_false_value(); }
/* * call-seq: * obj.inspect -> string * * Returns a string containing a human-readable representation of * <i>obj</i>. If not overridden and no instance variables, uses the * <code>to_s</code> method to generate the string. * <i>obj</i>. If not overridden, uses the <code>to_s</code> method to * generate the string. * * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]" * Time.new.inspect #=> "2008-03-08 19:43:39 +0900" */ mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value obj) { if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) { return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); } else if (mrb_nil_p(obj)) { return mrb_str_new(mrb, "nil", 3); } return mrb_funcall(mrb, obj, "to_s", 0, 0); }
/* * call-seq: * obj.inspect -> string * * Returns a string containing a human-readable representation of * <i>obj</i>. If not overridden and no instance variables, uses the * <code>to_s</code> method to generate the string. * <i>obj</i>. If not overridden, uses the <code>to_s</code> method to * generate the string. * * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]" * Time.new.inspect #=> "2008-03-08 19:43:39 +0900" */ mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value obj) { if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) { return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); } else if (mrb_type(obj) == MRB_TT_MAIN) { return mrb_str_new(mrb, "main", 4); } return mrb_any_to_s(mrb, obj); }
mrb_value cfunc_pointer_offset(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); int offset; mrb_get_args(mrb, "i", &offset); mrb_value ptr = cfunc_pointer_new_with_pointer(mrb, (void*)((uint8_t*)get_cfunc_pointer_data(data) + offset), false); mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern(mrb, "parent_pointer"), self); // keep for GC return ptr; }
/* * call-seq: * obj.instance_variable_defined?(symbol) -> true or false * * Returns <code>true</code> if the given instance variable is * defined in <i>obj</i>. * * class Fred * def initialize(p1, p2) * @a, @b = p1, p2 * end * end * fred = Fred.new('cat', 99) * fred.instance_variable_defined?(:@a) #=> true * fred.instance_variable_defined?("@b") #=> true * fred.instance_variable_defined?("@c") #=> false */ mrb_value mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) { mrb_sym mid; mrb_bool defined_p; mrb_get_args(mrb, "n", &mid); check_iv_name(mrb, mid); defined_p = mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid); return mrb_bool_value(defined_p); }
/* * call-seq: * obj.instance_variable_defined?(symbol) -> true or false * * Returns <code>true</code> if the given instance variable is * defined in <i>obj</i>. * * class Fred * def initialize(p1, p2) * @a, @b = p1, p2 * end * end * fred = Fred.new('cat', 99) * fred.instance_variable_defined?(:@a) #=> true * fred.instance_variable_defined?("@b") #=> true * fred.instance_variable_defined?("@c") #=> false */ mrb_value mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) { mrb_sym mid; mrb_value sym; mrb_bool defined_p; mrb_get_args(mrb, "o", &sym); mid = get_valid_iv_sym(mrb, sym); defined_p = mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid); return mrb_bool_value(defined_p); }
MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc) { mrb->exc = mrb_obj_ptr(exc); if (!mrb->out_of_memory) { exc_debug_info(mrb, mrb->exc); } if (!mrb->jmp) { mrb_p(mrb, exc); abort(); } MRB_THROW(mrb->jmp); }
mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym) { if (obj_iv_p(obj)) { iv_tbl *t = mrb_obj_ptr(obj)->iv; mrb_value val; if (t && iv_del(mrb, t, sym, &val)) { return val; } } return mrb_undef_value(); }
/* * call-seq: * obj.remove_instance_variable(symbol) -> obj * * Removes the named instance variable from <i>obj</i>, returning that * variable's value. * * class Dummy * attr_reader :var * def initialize * @var = 99 * end * def remove * remove_instance_variable(:@var) * end * end * d = Dummy.new * d.var #=> 99 * d.remove #=> 99 * d.var #=> nil */ mrb_value mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) { mrb_sym sym; mrb_value name; khash_t(iv) *h; khiter_t k; mrb_value val; mrb_value Qundef = mrb_undef_value(); mrb_get_args(mrb, "o", &name); sym = mrb_to_id(mrb, name); //if (OBJ_FROZEN(obj)) mrb_error_frozen("object"); //if (!mrb_is_instance_id(id)) { // mrb_name_error(mrb, id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id)); //} switch (mrb_type(self)) { case MRB_TT_OBJECT: case MRB_TT_CLASS: case MRB_TT_MODULE: if (!mrb_obj_ptr(self)->iv) break; h = mrb_obj_ptr(self)->iv; if (!h) break; k = kh_get(iv, h, sym); if (k != kh_end(h)) { val = kh_value(h, k); if (!mrb_obj_equal(mrb, val, Qundef)) { kh_value(h, k) = Qundef; return val; } } break; default: break; } mrb_name_error(mrb, sym, "instance variable %s not defined", mrb_sym2name(mrb, sym)); return mrb_nil_value(); /* not reached */ }