Example #1
0
File: gc.c Project: Everysick/mruby
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);
  }
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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);
}
Example #7
0
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;
}
Example #8
0
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);
    }
Example #9
0
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;
}