void mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data) { mrb_bool iterating = mrb->gc.iterating; mrb->gc.iterating = TRUE; if (iterating) { gc_each_objects(mrb, &mrb->gc, callback, data); } else { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; gc_each_objects(mrb, &mrb->gc, callback, data); mrb->jmp = prev_jmp; mrb->gc.iterating = iterating; } MRB_CATCH(&c_jmp) { mrb->gc.iterating = iterating; mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } MRB_END_EXC(&c_jmp); } }
MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data, mrb_int len, struct RClass **classes) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result; mrb_bool error_matched = FALSE; mrb_int i; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; result = body(mrb, b_data); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; for (i = 0; i < len; ++i) { if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), classes[i])) { error_matched = TRUE; break; } } if (!error_matched) { MRB_THROW(mrb->jmp); } mrb->exc = NULL; result = rescue(mrb, r_data); } MRB_END_EXC(&c_jmp); mrb_gc_protect(mrb, result); return result; }
static ssize_t mrb_wslay_event_recv_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len, int flags, void *user_data) { mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data; mrb_state*mrb = data->mrb; int ai = mrb_gc_arena_save(mrb); struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_int ret = -1; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; mrb_value argv[2]; argv[0] = mrb_cptr_value(mrb, buf); argv[1] = mrb_fixnum_value(len); errno = 0; mrb_assert(mrb_type(data->recv_callback) == MRB_TT_PROC); mrb_value buf_obj = mrb_yield_argv(mrb, data->recv_callback, NELEMS(argv), argv); if (mrb_fixnum_p(buf_obj)) { ret = mrb_fixnum(buf_obj); } else { buf_obj = mrb_str_to_str(mrb, buf_obj); ret = RSTRING_LEN(buf_obj); if (ret < 0||ret > len) { mrb_raise(mrb, E_RANGE_ERROR, "returned buf doesn't fit"); } if (ret > 0) { memmove(buf, (uint8_t *) RSTRING_PTR(buf_obj), ret); } } mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), mrb_class_get_under(mrb, mrb_module_get(mrb, "Errno"), "EAGAIN"))|| mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), mrb_class_get_under(mrb, mrb_module_get(mrb, "Errno"), "EWOULDBLOCK"))) { mrb->exc = NULL; wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); } else { wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); } } MRB_END_EXC(&c_jmp); mrb_gc_arena_restore(mrb, ai); return ret; }
static ssize_t mrb_wslay_event_send_callback(wslay_event_context_ptr ctx, const uint8_t *buf, size_t len, int flags, void *user_data) { mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data; mrb_state* mrb = data->mrb; int ai = mrb_gc_arena_save(mrb); struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_int ret = -1; MRB_TRY(&c_jmp) { data->mrb->jmp = &c_jmp; errno = 0; mrb_value buf_obj = mrb_str_new_static(mrb, (const char *) buf, len); mrb_assert(mrb_type(data->send_callback) == MRB_TT_PROC); mrb_value sent = mrb_yield(mrb, data->send_callback, buf_obj); ret = mrb_int(mrb, sent); mrb_assert(ret >= 0&&ret <= len); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), mrb_class_get_under(mrb, mrb_module_get(mrb, "Errno"), "EAGAIN"))|| mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), mrb_class_get_under(mrb, mrb_module_get(mrb, "Errno"), "EWOULDBLOCK"))) { mrb->exc = NULL; wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); } else { wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); } } MRB_END_EXC(&c_jmp); mrb_gc_arena_restore(mrb, ai); return ret; }
MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; result = body(mrb, b_data); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; ensure(mrb, e_data); MRB_THROW(mrb->jmp); /* rethrow catched exceptions */ } MRB_END_EXC(&c_jmp); ensure(mrb, e_data); mrb_gc_protect(mrb, result); return result; }
static void mrb_wslay_event_on_msg_recv_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_msg_recv_arg *arg, void *user_data) { mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data; mrb_state *mrb = data->mrb; int ai = mrb_gc_arena_save(mrb); struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; mrb_value argv[4]; argv[0] = mrb_fixnum_value(arg->rsv); argv[1] = MRB_GET_OPCODE(mrb_fixnum_value(arg->opcode)); argv[2] = mrb_str_new(mrb, (const char *) arg->msg, arg->msg_length); argv[3] = MRB_GET_STATUSCODE(mrb_fixnum_value(arg->status_code)); mrb_value on_msg_recv_arg = mrb_obj_new(mrb, mrb_class_get_under(mrb, mrb_module_get_under(mrb, mrb_module_get(mrb, "Wslay"), "Event"), "OnMsgRecvArg"), NELEMS(argv), argv); mrb_assert(mrb_type(data->on_msg_recv_callback) == MRB_TT_PROC); mrb_yield(mrb, data->on_msg_recv_callback, on_msg_recv_arg); mrb_gc_arena_restore(mrb, ai); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); mrb_gc_arena_restore(mrb, ai); MRB_THROW(mrb->jmp); } MRB_END_EXC(&c_jmp); }
MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result = mrb_nil_value(); if (state) { *state = FALSE; } MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; result = body(mrb, data); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; result = mrb_obj_value(mrb->exc); mrb->exc = NULL; if (state) { *state = TRUE; } } MRB_END_EXC(&c_jmp); mrb_gc_protect(mrb, result); return result; }
static int mrb_actor_pipe_reader(zloop_t* reactor, zsock_t* pipe, void* args) { errno = 0; self_t* self = (self_t*)args; int rc = 0; zmsg_t* msg = zmsg_recv(pipe); if (!msg) return -1; char* command = zmsg_popstr(msg); zsys_debug("command: %s", command); if (streq(command, "$TERM")) { rc = -1; } else if (streq(command, "BIND ROUTER")) { char* endpoint = zmsg_popstr(msg); if (zsock_bind(self->router, "%s", endpoint) >= 0) { const char* boundendpoint = zsock_endpoint(self->router); zyre_set_header(self->discovery, "mrb-actor-v1-router", "%s", boundendpoint); zsock_signal(pipe, 0); zsock_send(pipe, "s", boundendpoint); } else { zsock_signal(pipe, 1); zsock_send(pipe, "i", errno); } zstr_free(&endpoint); } else if (streq(command, "BIND PULL")) { char* endpoint = zmsg_popstr(msg); if (zsock_bind(self->pull, "%s", endpoint) >= 0) { const char* boundendpoint = zsock_endpoint(self->pull); zyre_set_header(self->discovery, "mrb-actor-v1-pull", "%s", boundendpoint); zsock_signal(pipe, 0); zsock_send(pipe, "s", boundendpoint); } else { zsock_signal(pipe, 1); zsock_send(pipe, "i", errno); } zstr_free(&endpoint); } else if (streq(command, "ZYRE SET ENDPOINT")) { char* endpoint = zmsg_popstr(msg); if (zyre_set_endpoint(self->discovery, "%s", endpoint) == -1) { zsock_signal(pipe, 1); } else { zsock_signal(pipe, 0); } zstr_free(&endpoint); } else if (streq(command, "ZYRE GOSSIP BIND")) { char* endpoint = zmsg_popstr(msg); zyre_gossip_bind(self->discovery, "%s", endpoint); zstr_free(&endpoint); } else if (streq(command, "ZYRE GOSSIP CONNECT")) { char* endpoint = zmsg_popstr(msg); zyre_gossip_connect(self->discovery, "%s", endpoint); zstr_free(&endpoint); } else if (streq(command, "ZYRE START")) { if (zyre_start(self->discovery) == -1) { zsock_signal(pipe, 1); } else { zyre_join(self->discovery, "mrb-actor-v1"); zsock_signal(pipe, 0); } } else if (streq(command, "LOAD IREP FILE")) { char* mrb_file = zmsg_popstr(msg); mrb_state* mrb = self->mrb; int ai = mrb_gc_arena_save(mrb); struct mrb_jmpbuf* prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; FILE* fp = fopen(mrb_file, "rb"); if (!fp) { mrb_sys_fail(mrb, "fopen"); } mrb_load_irep_file(mrb, fp); fclose(fp); if (mrb->exc) { mrb_exc_raise(mrb, mrb_obj_value(mrb->exc)); } zsock_signal(pipe, 0); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; mrb_print_error(mrb); zsock_signal(pipe, 1); mrb->exc = NULL; } MRB_END_EXC(&c_jmp); mrb_gc_arena_restore(mrb, ai); zstr_free(&mrb_file); }
int main(int argc, char **argv) { mrb_state *mrb = mrb_open(); int n = -1; int i; struct _args args; mrb_value ARGV; mrbc_context *c; mrb_value v; mrb_sym zero_sym; struct mrb_jmpbuf c_jmp; int ai; if (mrb == NULL) { fputs("Invalid mrb_state, exiting mruby\n", stderr); return EXIT_FAILURE; } n = parse_args(mrb, argc, argv, &args); if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) { cleanup(mrb, &args); usage(argv[0]); return n; } ai = mrb_gc_arena_save(mrb); MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; ARGV = mrb_ary_new_capa(mrb, args.argc); for (i = 0; i < args.argc; i++) { char* utf8 = mrb_utf8_from_locale(args.argv[i], -1); if (utf8) { mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8)); mrb_utf8_free(utf8); } } mrb_define_global_const(mrb, "ARGV", ARGV); c = mrbc_context_new(mrb); if (args.verbose) c->dump_result = TRUE; if (args.check_syntax) c->no_exec = TRUE; /* Set $0 */ zero_sym = mrb_intern_lit(mrb, "$0"); if (args.rfp) { const char *cmdline; cmdline = args.cmdline ? args.cmdline : "-"; mrbc_filename(mrb, c, cmdline); mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline)); } else { mrbc_filename(mrb, c, "-e"); mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e")); } /* Load program */ if (args.mrbfile) { v = mrb_load_irep_file_cxt(mrb, args.rfp, c); } else if (args.rfp) { v = mrb_load_file_cxt(mrb, args.rfp, c); } else { char* utf8 = mrb_utf8_from_locale(args.cmdline, -1); if (!utf8) abort(); v = mrb_load_string_cxt(mrb, utf8, c); mrb_utf8_free(utf8); } mrb_gc_arena_restore(mrb, ai); mrbc_context_free(mrb, c); if (mrb->exc) { if (!mrb_undef_p(v)) { mrb_print_error(mrb); } n = -1; } else if (args.check_syntax) { printf("Syntax OK\n"); } } MRB_CATCH(&c_jmp) { /* error */ } MRB_END_EXC(&c_jmp); cleanup(mrb, &args); return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }