Example #1
0
static void
load_rb_file(mrb_state *mrb, mrb_value filepath)
{
  FILE *file;
  char *fpath = RSTRING_PTR(filepath);
  mrbc_context *mrbc_ctx;

  {
    FILE *fp = fopen(fpath, "r");
    if (fp == NULL) {
      mrb_load_fail(mrb, filepath, "cannot load such file");
      return;
    }
    fclose(fp);
  }

  mrbc_ctx = mrbc_context_new(mrb);

  file = fopen((const char*)fpath, "r");
  mrbc_filename(mrb, mrbc_ctx, fpath);
  mrb_load_file_cxt(mrb, file, mrbc_ctx);
  fclose(file);

  mrbc_context_free(mrb, mrbc_ctx);
}
Example #2
0
static void
load_mrb_file(mrb_state *mrb, mrb_value filepath)
{
  char *fpath = RSTRING_PTR(filepath);
  int arena_idx;
  FILE *fp;
  mrb_irep *irep;

  {
    FILE *fp = fopen(fpath, "rb");
    if (fp == NULL) {
      mrb_load_fail(
        mrb,
        mrb_str_new_cstr(mrb, fpath),
        "cannot load such file"
      );
      return;
    }
    fclose(fp);
  }

  arena_idx = mrb_gc_arena_save(mrb);

  fp = fopen(fpath, "rb");
  irep = mrb_read_irep_file(mrb, fp);
  fclose(fp);

  mrb_gc_arena_restore(mrb, arena_idx);

  if (irep) {
    struct RProc *proc;
    /*
    size_t i;
    for (i = sirep; i < mrb->irep_len; i++) {
      mrb->irep[i]->filename = mrb_string_value_ptr(mrb, filepath);
    }
    */

    replace_stop_with_return(mrb, irep);
    proc = mrb_proc_new(mrb, irep);
    proc->target_class = mrb->object_class;

    arena_idx = mrb_gc_arena_save(mrb);
    mrb_yield_with_class(mrb, mrb_obj_value(proc), 0, NULL, mrb_top_self(mrb), mrb->object_class);
    mrb_gc_arena_restore(mrb, arena_idx);
  } else if (mrb->exc) {
    // fail to load
    longjmp(*(jmp_buf*)mrb->jmp, 1);
  }
}
Example #3
0
static void
load_so_file(mrb_state *mrb, mrb_value filepath)
{
  char entry[PATH_MAX] = {0}, *ptr, *top, *tmp;
  char entry_irep[PATH_MAX] = {0};
  typedef void (*fn_mrb_gem_init)(mrb_state *mrb);
  fn_mrb_gem_init fn;
  void * handle = dlopen(RSTRING_PTR(filepath), RTLD_LAZY|RTLD_GLOBAL);
  const uint8_t* data;
  if (!handle) {
    mrb_raise(mrb, E_RUNTIME_ERROR, dlerror());
  }
  dlerror(); // clear last error

  tmp = top = ptr = strdup(RSTRING_PTR(filepath));
  while (tmp) {
    if ((tmp = strchr(ptr, '/')) || (tmp = strchr(ptr, '\\'))) {
      ptr = tmp + 1;
    }
  }

  tmp = strrchr(ptr, '.');
  if (tmp) *tmp = 0;
  tmp = ptr;
  while (*tmp) {
    if (*tmp == '-') *tmp = '_';
    tmp++;
  }
  snprintf(entry, sizeof(entry)-1, "mrb_%s_gem_init", ptr);
  snprintf(entry_irep, sizeof(entry_irep)-1, "gem_mrblib_irep_%s", ptr);
  fn = (fn_mrb_gem_init) dlsym(handle, entry);
  data = (const uint8_t *)dlsym(handle, entry_irep);
  free(top);
  if (!fn && !data) {
      mrb_load_fail(mrb, filepath, "cannot load such file");
  }

  if (fn != NULL) {
    int ai = mrb_gc_arena_save(mrb);
    fn(mrb);
    mrb_gc_arena_restore(mrb, ai);
  }
  dlerror(); // clear last error

  if (data != NULL) {
    mrb_load_irep_data(mrb, data);
  }
}
Example #4
0
static void
load_mrb_file(mrb_state *mrb, mrb_value filepath)
{
  char *fpath = RSTRING_PTR(filepath);
  int ai;
  FILE *fp;
  mrb_irep *irep;

  fp = fopen(fpath, "rb");
  if (fp == NULL) {
    mrb_load_fail(
      mrb,
      mrb_str_new_cstr(mrb, fpath),
      "cannot load such file"
    );
    return;
  }

  ai = mrb_gc_arena_save(mrb);

  irep = mrb_read_irep_file(mrb, fp);
  fclose(fp);

  mrb_gc_arena_restore(mrb, ai);

  if (irep) {
    struct RProc *proc;
    /*
    size_t i;
    for (i = sirep; i < mrb->irep_len; i++) {
      mrb->irep[i]->filename = mrb_string_value_ptr(mrb, filepath);
    }
    */

#ifdef USE_MRUBY_OLD_BYTE_CODE
    replace_stop_with_return(mrb, irep);
#endif
    proc = mrb_proc_new(mrb, irep);
    MRB_PROC_SET_TARGET_CLASS(proc, mrb->object_class);

    ai = mrb_gc_arena_save(mrb);
    mrb_yield_with_class(mrb, mrb_obj_value(proc), 0, NULL, mrb_top_self(mrb), mrb->object_class);
    mrb_gc_arena_restore(mrb, ai);
  } else if (mrb->exc) {
    // fail to load
    longjmp(*(jmp_buf*)mrb->jmp, 1);
  }
}
Example #5
0
static mrb_value
find_file_check(mrb_state *mrb, mrb_value path, mrb_value fname, mrb_value ext)
{
  FILE *fp;
  char fpath[MAXPATHLEN];
  mrb_value filepath = mrb_str_dup(mrb, path);
#ifdef _WIN32
  if (RSTRING_PTR(fname)[1] == ':') {
#else
  if (RSTRING_PTR(fname)[0] == '/') {
#endif
    /* when absolute path */
    mrb_funcall(mrb, filepath, "replace", 1, fname);
  } else {
    mrb_str_cat2(mrb, filepath, "/");
    mrb_str_buf_append(mrb, filepath, fname);
  }

  if (!mrb_string_p(filepath)) {
    return mrb_nil_value();
  }
  if (mrb_string_p(ext)) {
    mrb_str_buf_append(mrb, filepath, ext);
  }
  debug("filepath: %s\n", RSTRING_PTR(filepath));

  if (realpath(RSTRING_PTR(filepath), fpath) == NULL) {
    return mrb_nil_value();
  }
  debug("fpath: %s\n", fpath);

  fp = fopen(fpath, "r");
  if (fp == NULL) {
    return mrb_nil_value();
  }
  fclose(fp);

  return mrb_str_new_cstr(mrb, fpath);
}

static mrb_value
find_file(mrb_state *mrb, mrb_value filename, int comp)
{
  char *ext, *ptr, *tmp;
  mrb_value exts;
  int i, j;

  char *fname = RSTRING_PTR(filename);
  mrb_value filepath = mrb_nil_value();
  mrb_value load_path = mrb_obj_dup(mrb, mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$:")));
  load_path = mrb_check_array_type(mrb, load_path);

  if(mrb_nil_p(load_path)) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "invalid $:");
    return mrb_undef_value();
  }

  tmp = ptr = fname;
  while (tmp) {
    if ((tmp = strchr(ptr, '/')) || (tmp = strchr(ptr, '\\'))) {
      ptr = tmp + 1;
    }
  }

  ext = strrchr(ptr, '.');
  exts = mrb_ary_new(mrb);
  if (ext == NULL && comp) {
    mrb_ary_push(mrb, exts, mrb_str_new_cstr(mrb, ".rb"));
    mrb_ary_push(mrb, exts, mrb_str_new_cstr(mrb, ".mrb"));
    mrb_ary_push(mrb, exts, mrb_str_new_cstr(mrb, ".so"));
  } else {
    mrb_ary_push(mrb, exts, mrb_nil_value());
  }

  /* when a filename start with '.', $: = ['.'] */
  if (*fname == '.') {
    load_path = mrb_ary_new(mrb);
    mrb_ary_push(mrb, load_path, mrb_str_new_cstr(mrb, "."));
  }

  for (i = 0; i < RARRAY_LEN(load_path); i++) {
    for (j = 0; j < RARRAY_LEN(exts); j++) {
      filepath = find_file_check(
        mrb,
        mrb_ary_entry(load_path, i),
        filename,
        mrb_ary_entry(exts, j));
      if (!mrb_nil_p(filepath)) {
        return filepath;
      }
    }
  }

  mrb_load_fail(mrb, filename, "cannot load such file");
  return mrb_nil_value();
}