コード例 #1
0
ファイル: atfile.c プロジェクト: bobot/extunix
CAMLprim value caml_extunix_openat(value v_dirfd, value path, value flags, value perm)
{
  CAMLparam4(v_dirfd, path, flags, perm);
  int ret, cv_flags;
  char * p;

  cv_flags = extunix_open_flags(flags);
  p = caml_stat_alloc(caml_string_length(path) + 1);
  strcpy(p, String_val(path));
  /* open on a named FIFO can block (PR#1533) */
  caml_enter_blocking_section();
  ret = openat(Int_val(v_dirfd), p, cv_flags, Int_val(perm));
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (ret == -1) uerror("openat", path);
  CAMLreturn (Val_int(ret));
}
コード例 #2
0
ファイル: unix.c プロジェクト: crackleware/ocamlcc
char * caml_search_exe_in_path(const char * name)
{
  struct ext_table path;
  char * tofree;
  char * res;

  caml_ext_table_init(&path, 8);
  tofree = caml_decompose_path(&path, getenv("PATH"));
#ifndef __CYGWIN32__
  res = caml_search_in_path(&path, name);
#else
  res = cygwin_search_exe_in_path(&path, name);
#endif
  caml_stat_free(tofree);
  caml_ext_table_free(&path, 0);
  return res;
}
コード例 #3
0
ファイル: atfile.c プロジェクト: bobot/extunix
CAMLprim value caml_extunix_readlinkat(value v_dirfd, value v_name)
{
  CAMLparam2(v_dirfd, v_name);
  CAMLlocal1(v_link);
  char* res;
  char* p = caml_stat_alloc(caml_string_length(v_name) + 1);
  strcpy(p, String_val(v_name));

  caml_enter_blocking_section();
  res = readlinkat_malloc(Int_val(v_dirfd), p);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (res == NULL) uerror("readlinkat", v_name);
  v_link = caml_copy_string(res);
  free(res);
  CAMLreturn(v_link);
}
コード例 #4
0
ファイル: execvp.c プロジェクト: dhil/ocaml-multicore
CAMLprim value unix_execvpe(value path, value args, value env)
{
  char_os ** argv;
  char_os ** envp;
  char_os * wpath;
  caml_unix_check_path(path, "execvpe");
  argv = cstringvect(args, "execvpe");
  envp = cstringvect(env, "execvpe");
  wpath = caml_stat_strdup_to_os(String_val(path));
  (void) execvpe_os((const char_os *)wpath, EXECV_CAST argv, EXECV_CAST envp);
  caml_stat_free(wpath);
  cstringvect_free(argv);
  cstringvect_free(envp);
  uerror("execvpe", path);
  return Val_unit;                  /* never reached, but suppress warnings */
                                    /* from smart compilers */
}
コード例 #5
0
ファイル: opendir.c プロジェクト: clappski/ocaml-multicore
CAMLprim value unix_opendir(value path)
{
  CAMLparam1(path);
  DIR * d;
  value res;
  char * p;

  p = caml_strdup(String_val(path));
  caml_enter_blocking_section();
  d = opendir(p);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (d == (DIR *) NULL) uerror("opendir", path);
  res = alloc_small(1, Abstract_tag);
  DIR_Val(res) = d;
  CAMLreturn(res);
}
コード例 #6
0
ファイル: io.c プロジェクト: pgj/mirage-platform
void
caml_close_all_channels(void)
{
  struct channel * ch, *p;

  ch = p = caml_all_opened_channels;
  while (ch != NULL) {
    p = ch;
    ch = ch->prev;
  }
  ch = p;
  while (ch != NULL) {
    p = ch->next;
    caml_stat_free(ch);
    ch = p;
  }
}
コード例 #7
0
ファイル: zmq_stubs.c プロジェクト: hcarty/ocaml-zmq3
CAMLprim value connect_stub(value sock, value string_address) {
    CAMLparam2 (sock, string_address);
    char buffer[BUFF_THRESHOLD];
    struct wrap *socket = Socket_val(sock);
    int alloced = 0;
    char *strcopy = copy_with_stack_buffer(buffer,
                                           sizeof(buffer),
                                           string_address,
                                           &alloced);

    caml_release_runtime_system();
    int result = zmq_connect(socket->wrapped, strcopy);
    caml_acquire_runtime_system();

    if (alloced) caml_stat_free(strcopy);
    stub_raise_if (result == -1);
    CAMLreturn(Val_unit);
}
コード例 #8
0
ファイル: dynlink.c プロジェクト: bluddy/ocaml-multicore
CAMLprim value caml_dynlink_open_lib(value mode, value filename)
{
  void * handle;
  value result;
  char * p;

  caml_gc_log("Opening shared library %s", String_val(filename));
  p = caml_strdup(String_val(filename));
  caml_enter_blocking_section();
  handle = caml_dlopen(p, Int_val(mode), 1);
  caml_leave_blocking_section();
  caml_stat_free(p);

  if (handle == NULL) caml_failwith(caml_dlerror());
  result = caml_alloc_small(1, Abstract_tag);
  Handle_val(result) = handle;
  return result;
}
コード例 #9
0
ファイル: sys.c プロジェクト: BrianMulhall/ocaml
CAMLprim value caml_sys_system_command(value command)
{
  CAMLparam1 (command);
  int status, retcode;
  char *buf;

  buf = caml_strdup(String_val(command));
  caml_enter_blocking_section ();
  status = system(buf);
  caml_leave_blocking_section ();
  caml_stat_free(buf);
  if (status == -1) caml_sys_error(command);
  if (WIFEXITED(status))
    retcode = WEXITSTATUS(status);
  else
    retcode = 255;
  CAMLreturn (Val_int(retcode));
}
コード例 #10
0
ファイル: stat.c プロジェクト: bluddy/ocaml-multicore
CAMLprim value unix_lstat_64(value path)
{
  CAMLparam1(path);
  int ret;
  struct stat buf;
  char * p;
  p = caml_strdup(String_val(path));
  caml_enter_blocking_section();
#ifdef HAS_SYMLINK
  ret = lstat(p, &buf);
#else
  ret = stat(p, &buf);
#endif
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (ret == -1) uerror("lstat", path);
  CAMLreturn(stat_aux(1, &buf));
}
コード例 #11
0
ファイル: atfile.c プロジェクト: bobot/extunix
CAMLprim value caml_extunix_fstatat(value v_dirfd, value v_name, value v_flags)
{
  CAMLparam3(v_dirfd, v_name, v_flags);
  int ret;
  struct stat buf;
  char* p = caml_stat_alloc(caml_string_length(v_name) + 1);
  int flags = caml_convert_flag_list(v_flags, at_flags_table);
  flags &= (AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT); /* only allowed flags here */

  strcpy(p, String_val(v_name));
  caml_enter_blocking_section();
  ret = fstatat(Int_val(v_dirfd), p, &buf, flags);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (ret != 0) uerror("fstatat", v_name);
  if (buf.st_size > Max_long && (buf.st_mode & S_IFMT) == S_IFREG)
    unix_error(EOVERFLOW, "fstatat", v_name);
  CAMLreturn(stat_aux(/*0,*/ &buf));
}
コード例 #12
0
ファイル: select.c プロジェクト: bmeurer/ocaml-arm
/* Free select data */
void select_data_free (LPSELECTDATA lpSelectData)
{
  DWORD i;

  DEBUG_PRINT("Freeing data of %x", lpSelectData);

  /* Free APC related data, if they exists */
  if (lpSelectData->lpWorker != NULL)
  {
    worker_job_finish(lpSelectData->lpWorker);
    lpSelectData->lpWorker = NULL;
  };

  /* Make sure results/queries cannot be accessed */
  lpSelectData->nResultsCount = 0;
  lpSelectData->nQueriesCount = 0;

  caml_stat_free(lpSelectData);
}
コード例 #13
0
ファイル: binding_epoll.c プロジェクト: Akhavi/opalang
value ep_wait(value v_epfd, value v_maxevents, value v_timeout)
{
	CAMLparam3(v_epfd, v_maxevents, v_timeout);
	CAMLlocal2(v_res, v_flags);
	int maxevents = Int_val(v_maxevents);
	struct epoll_event *evs;
	int nb;

	if (maxevents <= 0) caml_invalid_argument("epoll_wait: maxevents <= 0");

	/* evs = caml_stat_alloc(maxevents); */
	evs = malloc(maxevents * sizeof (struct epoll_event));

	caml_release_runtime_system();
	nb = epoll_wait(Int_val(v_epfd), evs, maxevents, Int_val(v_timeout));
	caml_acquire_runtime_system();

	if (nb == -1) {
		caml_stat_free(evs);
		int err = errno;
		errno = 0;
		caml_failwith(strerror(err));
	}

	v_res = caml_alloc(nb, 0);

	/* FIXME? */
	while (--nb >= 0) {
		value v_ev;
		struct epoll_event *ev = &evs[nb];
		//v_flags = caml_copy_int32(ev->events); WHY THIS ??
		v_ev = caml_alloc_small(2, 0);
		Field(v_ev, 0) = Val_int(ev->data.fd);
		Field(v_ev, 1) = Val_int(ev->events); // v_flags replaced with ev->events
		Store_field(v_res, nb, v_ev);
	}

	free(evs);
	/* caml_stat_free(evs); */

	CAMLreturn(v_res);
}
コード例 #14
0
ファイル: shmem_stubs.c プロジェクト: avsm/ocaml-workflow
value
ocaml_shm_open(value v_name, value v_rw, value v_creat, value v_excl, value v_trunc)
{
  CAMLparam5(v_name, v_rw, v_creat, v_excl, v_trunc);
  char *path;
  int fd;
  int flags = (Bool_val(v_rw)) ? O_RDWR : O_RDONLY;
  if (Bool_val(v_creat)) flags |= O_CREAT;
  if (Bool_val(v_excl)) flags |= O_EXCL;
  if (Bool_val(v_trunc)) flags |= O_TRUNC;
  path = caml_stat_alloc(caml_string_length(v_name)+1);
  strcpy(path, String_val(v_name)); 
  enter_blocking_section();
  fd = shm_open(path, flags, S_IRUSR | S_IWUSR);
  leave_blocking_section();
  caml_stat_free(path);
  if (fd == -1)
    uerror("shm_open", v_name);
  CAMLreturn(Val_int(fd));
}
コード例 #15
0
ファイル: stat.c プロジェクト: bluddy/ocaml-multicore
CAMLprim value unix_lstat(value path)
{
  CAMLparam1(path);
  int ret;
  struct stat buf;
  char * p;
  p = caml_strdup(String_val(path));
  caml_enter_blocking_section();
#ifdef HAS_SYMLINK
  ret = lstat(p, &buf);
#else
  ret = stat(p, &buf);
#endif
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (ret == -1) uerror("lstat", path);
  if (buf.st_size > Max_long && (buf.st_mode & S_IFMT) == S_IFREG)
    unix_error(EOVERFLOW, "lstat", path);
  CAMLreturn(stat_aux(0, &buf));
}
コード例 #16
0
ファイル: unix.c プロジェクト: bluddy/ocaml-multicore
char * caml_search_in_path(struct ext_table * path, char * name)
{
  char * p, * dir, * fullname;
  int i;
  struct stat st;

  for (p = name; *p != 0; p++) {
    if (*p == '/') goto not_found;
  }
  for (i = 0; i < path->size; i++) {
    dir = path->contents[i];
    if (dir[0] == 0) dir = ".";  /* empty path component = current dir */
    fullname = caml_strconcat(3, dir, "/", name);
    if (stat(fullname, &st) == 0 && S_ISREG(st.st_mode))
      return fullname;
    caml_stat_free(fullname);
  }
 not_found:
  return caml_strdup(name);
}
コード例 #17
0
ファイル: minor_gc.c プロジェクト: bluddy/ocaml-multicore
CAMLexport value caml_promote(struct domain* domain, value root)
{
  struct promotion_stack stk = {0};

  if (Is_long(root))
    /* Integers are already shared */
    return root;

  if (Tag_val(root) == Stack_tag)
    /* Stacks are handled specially */
    return promote_stack(domain, root);

  if (!Is_minor(root))
    /* This value is already shared */
    return root;

  Assert(caml_owner_of_young_block(root) == domain);

  value ret = caml_promote_one(&stk, domain, root);

  while (stk.sp > 0) {
    struct promotion_stack_entry* curr = &stk.stack[stk.sp - 1];
    value local = curr->local;
    value global = curr->global;
    int field = curr->field;
    Assert(field < Wosize_val(local));
    curr->field++;
    if (curr->field == Wosize_val(local))
      stk.sp--;
    value x = Op_val(local)[field];
    if (Is_block(x) && Tag_val(x) == Stack_tag) {
      /* stacks are not promoted unless explicitly requested */
      Ref_table_add(&domain->state->remembered_set->ref, global, field);
    } else {
      x = caml_promote_one(&stk, domain, x);
    }
    Op_val(local)[field] = Op_val(global)[field] = x;
  }
  caml_stat_free(stk.stack);
  return ret;
}
コード例 #18
0
ファイル: sys.c プロジェクト: joechenq/multi-script
CAMLprim value caml_sys_open(value path, value vflags, value vperm)
{
  CAMLparam3(path, vflags, vperm);
  int fd, flags, perm;
  char * p;

  p = caml_stat_alloc(caml_string_length(path) + 1);
  strcpy(p, String_val(path));
  flags = caml_convert_flag_list(vflags, sys_open_flags);
  perm = Int_val(vperm);
  /* open on a named FIFO can block (PR#1533) */
  caml_enter_blocking_section();
  fd = open(p, flags, perm);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (fd == -1) caml_sys_error(path);
#if defined(F_SETFD) && defined(FD_CLOEXEC)
  fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
  CAMLreturn(Val_long(fd));
}
コード例 #19
0
ファイル: floats.c プロジェクト: jessicah/snowflake-svn
CAMLprim value caml_format_float(value fmt, value arg)
{
#define MAX_DIGITS 350
/* Max number of decimal digits in a "natural" (not artificially padded)
   representation of a float. Can be quite big for %f format.
   Max exponent for IEEE format is 308 decimal digits.
   Rounded up for good measure. */
  char format_buffer[MAX_DIGITS + 20];
  int prec, i;
  char * p;
  char * dest;
  value res;

  prec = MAX_DIGITS;
  for (p = String_val(fmt); *p != 0; p++) {
    if (*p >= '0' && *p <= '9') {
      i = atoi(p) + MAX_DIGITS;
      if (i > prec) prec = i;
      break;
    }
  }
  for( ; *p != 0; p++) {
    if (*p == '.') {
      i = atoi(p+1) + MAX_DIGITS;
      if (i > prec) prec = i;
      break;
    }
  }
  if (prec < sizeof(format_buffer)) {
    dest = format_buffer;
  } else {
    dest = caml_stat_alloc(prec);
  }
  sprintf(dest, String_val(fmt), Double_val(arg));
  res = caml_copy_string(dest);
  if (dest != format_buffer) {
    caml_stat_free(dest);
  }
  return res;
}
コード例 #20
0
CAMLprim value caml_format_int(value fmt, value arg)
{
  char format_string[FORMAT_BUFFER_SIZE];
  char default_format_buffer[FORMAT_BUFFER_SIZE];
  char * buffer;
  char conv;
  value res;

  buffer = parse_format(fmt, ARCH_INTNAT_PRINTF_FORMAT,
			format_string, default_format_buffer, &conv);
  switch (conv) {
  case 'u': case 'x': case 'X': case 'o':
    sprintf(buffer, format_string, Unsigned_long_val(arg));
    break;
  default:
    sprintf(buffer, format_string, Long_val(arg));
    break;
  }
  res = caml_copy_string(buffer);
  if (buffer != default_format_buffer) caml_stat_free(buffer);
  return res;
}
コード例 #21
0
ファイル: bigarray_stubs.c プロジェクト: avsm/mirage-kfreebsd
static void caml_ba_finalize(value v)
{
  struct caml_ba_array * b = Caml_ba_array_val(v);

  switch (b->flags & CAML_BA_MANAGED_MASK) {
  case CAML_BA_EXTERNAL:
    break;
  case CAML_BA_MANAGED:
    if (b->proxy == NULL) {
      __free(b->data);
    } else {
      if (-- b->proxy->refcount == 0) {
        __free(b->proxy->data);
        caml_stat_free(b->proxy);
      }
    }
    break;
  case CAML_BA_MAPPED_FILE:
    caml_failwith("CAML_BA_MAPPED_FILE: unsupported");
    break;
  }
}
コード例 #22
0
ファイル: sys.c プロジェクト: BrianMulhall/ocaml
CAMLprim value caml_sys_file_exists(value name)
{
#ifdef _WIN32
  struct _stati64 st;
#else
  struct stat st;
#endif
  char * p;
  int ret;

  p = caml_strdup(String_val(name));
  caml_enter_blocking_section();
#ifdef _WIN32
  ret = _stati64(p, &st);
#else
  ret = stat(p, &st);
#endif
  caml_leave_blocking_section();
  caml_stat_free(p);

  return Val_bool(ret == 0);
}
コード例 #23
0
ファイル: unix.c プロジェクト: ArnaudParant/install_script
char * caml_search_in_path(struct ext_table * path, char * name)
{
  char * p, * fullname;
  int i;
  struct stat st;

  for (p = name; *p != 0; p++) {
    if (*p == '/') goto not_found;
  }
  for (i = 0; i < path->size; i++) {
    fullname = caml_stat_alloc(strlen((char *)(path->contents[i])) +
                               strlen(name) + 2);
    strcpy(fullname, (char *)(path->contents[i]));
    if (fullname[0] != 0) strcat(fullname, "/");
    strcat(fullname, name);
    if (stat(fullname, &st) == 0 && S_ISREG(st.st_mode)) return fullname;
    caml_stat_free(fullname);
  }
 not_found:
  fullname = caml_stat_alloc(strlen(name) + 1);
  strcpy(fullname, name);
  return fullname;
}
コード例 #24
0
ファイル: sys.c プロジェクト: BrianMulhall/ocaml
CAMLprim value caml_sys_read_directory(value path)
{
  CAMLparam1(path);
  CAMLlocal1(result);
  struct ext_table tbl;
  char * p;
  int ret;

  caml_ext_table_init(&tbl, 50);
  p = caml_strdup(String_val(path));
  caml_enter_blocking_section();
  ret = caml_read_directory(p, &tbl);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (ret == -1){
    caml_ext_table_free(&tbl, 1);
    caml_sys_error(path);
  }
  caml_ext_table_add(&tbl, NULL);
  result = caml_copy_string_array((char const **) tbl.contents);
  caml_ext_table_free(&tbl, 1);
  CAMLreturn(result);
}
コード例 #25
0
ファイル: win32.c プロジェクト: bobzhang/ocaml
char * caml_search_in_path(struct ext_table * path, char * name)
{
    char * p, * dir, * fullname;
    int i;
    struct stat st;

    for (p = name; *p != 0; p++) {
        if (*p == '/' || *p == '\\') goto not_found;
    }
    for (i = 0; i < path->size; i++) {
        dir = path->contents[i];
        if (dir[0] == 0) continue;
        /* not sure what empty path components mean under Windows */
        fullname = caml_strconcat(3, dir, "\\", name);
        caml_gc_message(0x100, "Searching %s\n", (uintnat) fullname);
        if (stat(fullname, &st) == 0 && S_ISREG(st.st_mode))
            return fullname;
        caml_stat_free(fullname);
    }
not_found:
    caml_gc_message(0x100, "%s not found in search path\n", (uintnat) name);
    return caml_strdup(name);
}
コード例 #26
0
ファイル: stacks.c プロジェクト: balrajsingh/mirage-platform
void caml_realloc_stack(asize_t required_space)
{
  asize_t size;
  value * new_low, * new_high, * new_sp;
  value * p;

  Assert(caml_extern_sp >= caml_stack_low);
  size = caml_stack_high - caml_stack_low;
  do {
    if (size >= caml_max_stack_size) caml_raise_stack_overflow();
    size *= 2;
  } while (size < caml_stack_high - caml_extern_sp + required_space);
  caml_gc_message (0x08, "Growing stack to %"
                         ARCH_INTNAT_PRINTF_FORMAT "uk bytes\n",
                   (uintnat) size * sizeof(value) / 1024);
  new_low = (value *) caml_stat_alloc(size * sizeof(value));
  new_high = new_low + size;

#define shift(ptr) \
    ((char *) new_high - ((char *) caml_stack_high - (char *) (ptr)))

  new_sp = (value *) shift(caml_extern_sp);
  memmove((char *) new_sp,
          (char *) caml_extern_sp,
          (caml_stack_high - caml_extern_sp) * sizeof(value));
  caml_stat_free(caml_stack_low);
  caml_trapsp = (value *) shift(caml_trapsp);
  caml_trap_barrier = (value *) shift(caml_trap_barrier);
  for (p = caml_trapsp; p < new_high; p = Trap_link(p))
    Trap_link(p) = (value *) shift(Trap_link(p));
  caml_stack_low = new_low;
  caml_stack_high = new_high;
  caml_stack_threshold = caml_stack_low + Stack_threshold / sizeof (value);
  caml_extern_sp = new_sp;

#undef shift
}
コード例 #27
0
ファイル: pcre_stubs.c プロジェクト: mmottl/pcre-ocaml
CAMLprim value pcre_exec_stub0(
    intnat v_opt, value v_rex, intnat v_pos, intnat v_subj_start, value v_subj,
    value v_ovec, value v_maybe_cof, value v_workspace)
{
  int ret;
  int is_dfa = v_workspace != (value) NULL;
  long
    pos = v_pos,
    len = caml_string_length(v_subj),
    subj_start = v_subj_start;
  long ovec_len = Wosize_val(v_ovec);

  if (pos > len || pos < subj_start)
    caml_invalid_argument("Pcre.pcre_exec_stub: illegal position");

  if (subj_start > len || subj_start < 0)
    caml_invalid_argument("Pcre.pcre_exec_stub: illegal subject start");

  pos -= subj_start;
  len -= subj_start;

  {
    const pcre *code = get_rex(v_rex);  /* Compiled pattern */
    const pcre_extra *extra = get_extra(v_rex);  /* Extra info */
    const char *ocaml_subj =
      String_val(v_subj) + subj_start;  /* Subject string */
    const int opt = v_opt;  /* Runtime options */

    /* Special case when no callout functions specified */
    if (v_maybe_cof == None) {
      int *ovec = (int *) &Field(v_ovec, 0);

      /* Performs the match */
      if (is_dfa)
        ret =
          pcre_dfa_exec(code, extra, ocaml_subj, len, pos, opt, ovec, ovec_len,
              (int *) &Field(v_workspace, 0), Wosize_val(v_workspace));
      else
        ret = pcre_exec(code, extra, ocaml_subj, len, pos, opt, ovec, ovec_len);

      if (ret < 0) handle_exec_error("pcre_exec_stub", ret);
      else handle_pcre_exec_result(ovec, v_ovec, ovec_len, subj_start, ret);
    }

    /* There are callout functions */
    else {
      value v_cof = Field(v_maybe_cof, 0);
      value v_substrings;
      char *subj = caml_stat_alloc(sizeof(char) * len);
      int *ovec = caml_stat_alloc(sizeof(int) * ovec_len);
      int workspace_len;
      int *workspace;
      struct cod cod = { 0, (value *) NULL, (value *) NULL, (value) NULL };
      struct pcre_extra new_extra =
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
# ifdef PCRE_EXTRA_MARK
#  ifdef PCRE_EXTRA_EXECUTABLE_JIT
        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0, NULL, NULL };
#  else
        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0, NULL };
#  endif
# else
        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0 };
# endif
#else
        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL };
#endif

      cod.subj_start = subj_start;
      memcpy(subj, ocaml_subj, len);

      Begin_roots4(v_rex, v_cof, v_substrings, v_ovec);
        Begin_roots1(v_subj);
          v_substrings = caml_alloc_small(2, 0);
        End_roots();

        Field(v_substrings, 0) = v_subj;
        Field(v_substrings, 1) = v_ovec;

        cod.v_substrings_p = &v_substrings;
        cod.v_cof_p = &v_cof;
        new_extra.callout_data = &cod;

        if (extra != NULL) {
          new_extra.flags = PCRE_EXTRA_CALLOUT_DATA | extra->flags;
          new_extra.study_data = extra->study_data;
          new_extra.match_limit = extra->match_limit;
          new_extra.tables = extra->tables;
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
          new_extra.match_limit_recursion = extra->match_limit_recursion;
#endif
        }

        if (is_dfa) {
          workspace_len = Wosize_val(v_workspace);
          workspace = caml_stat_alloc(sizeof(int) * workspace_len);
          ret =
            pcre_dfa_exec(code, extra, subj, len, pos, opt, ovec, ovec_len,
                (int *) &Field(v_workspace, 0), workspace_len);
        } else
          ret =
            pcre_exec(code, &new_extra, subj, len, pos, opt, ovec, ovec_len);

        caml_stat_free(subj);
      End_roots();

      if (ret < 0) {
        if (is_dfa) caml_stat_free(workspace);
        caml_stat_free(ovec);
        if (ret == PCRE_ERROR_CALLOUT) caml_raise(cod.v_exn);
        else handle_exec_error("pcre_exec_stub(callout)", ret);
      } else {
        handle_pcre_exec_result(ovec, v_ovec, ovec_len, subj_start, ret);
        if (is_dfa) {
          caml_int_ptr ocaml_workspace_dst =
            (caml_int_ptr) &Field(v_workspace, 0);
          const int *workspace_src = workspace;
          const int *workspace_src_stop = workspace + workspace_len;
          while (workspace_src != workspace_src_stop) {
            *ocaml_workspace_dst = *workspace_src;
            ocaml_workspace_dst++;
            workspace_src++;
          }
          caml_stat_free(workspace);
        }
        caml_stat_free(ovec);
      }
    }
  }

  return Val_unit;
}

CAMLprim value pcre_exec_stub(
    intnat v_opt, value v_rex, intnat v_pos, intnat v_subj_start, value v_subj,
    value v_ovec, value v_maybe_cof)
{
  return pcre_exec_stub0(v_opt, v_rex, v_pos, v_subj_start, v_subj,
                         v_ovec, v_maybe_cof, (value) NULL);
}

/* Byte-code hook for pcre_exec_stub
   Needed, because there are more than 5 arguments */
CAMLprim value pcre_exec_stub_bc(value *argv, int __unused argn)
{
  return
    pcre_exec_stub0(
        Int_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
        argv[4], argv[5], argv[6], (value) NULL);
}

/* Byte-code hook for pcre_dfa_exec_stub
   Needed, because there are more than 5 arguments */
CAMLprim value pcre_dfa_exec_stub_bc(value *argv, int __unused argn)
{
  return
    pcre_exec_stub0(
        Int_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
        argv[4], argv[5], argv[6], argv[7]);
}

static struct custom_operations tables_ops = {
  "pcre_ocaml_tables",
  pcre_dealloc_tables,
  custom_compare_default,
  custom_hash_default,
  custom_serialize_default,
  custom_deserialize_default,
  custom_compare_ext_default
};

/* Generates a new set of chartables for the current locale (see man
   page of PCRE */
CAMLprim value pcre_maketables_stub(value __unused v_unit)
{
  /* GC will do a full cycle every 1_000_000 table set allocations (one
     table set consumes 864 bytes -> maximum of 864_000_000 bytes unreclaimed
     table sets) */
  const value v_tables =
    caml_alloc_custom(
        &tables_ops, sizeof(struct pcre_ocaml_tables), 1, 1000000);
  set_tables(v_tables, pcre_maketables());
  return v_tables;
}

/* Wraps around the isspace-function */
CAMLprim value pcre_isspace_stub(value v_c)
{
  return Val_bool(isspace(Int_val(v_c)));
}


/* Returns number of substring associated with a name */

CAMLprim intnat pcre_get_stringnumber_stub(value v_rex, value v_name)
{
  const int ret = pcre_get_stringnumber(get_rex(v_rex), String_val(v_name));
  if (ret == PCRE_ERROR_NOSUBSTRING)
    caml_invalid_argument("Named string not found");

  return ret;
}

CAMLprim value pcre_get_stringnumber_stub_bc(value v_rex, value v_name)
{
  return Val_int(pcre_get_stringnumber_stub(v_rex, v_name));
}


/* Returns array of names of named substrings in a regexp */
CAMLprim value pcre_names_stub(value v_rex)
{
  CAMLparam0();
  CAMLlocal1(v_res);
  int name_count;
  int entry_size;
  const char *tbl_ptr;
  int i;

  int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMECOUNT, &name_count);
  if (ret != 0) raise_internal_error("pcre_names_stub: namecount");

  ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMEENTRYSIZE, &entry_size);
  if (ret != 0) raise_internal_error("pcre_names_stub: nameentrysize");

  ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMETABLE, &tbl_ptr);
  if (ret != 0) raise_internal_error("pcre_names_stub: nametable");

  v_res = caml_alloc(name_count, 0);

  for (i = 0; i < name_count; ++i) {
    value v_name = caml_copy_string(tbl_ptr + 2);
    Store_field(v_res, i, v_name);
    tbl_ptr += entry_size;
  }

  CAMLreturn(v_res);
}

/* Generic stub for getting integer results from pcre_config */
static inline int pcre_config_int(int what)
{
  int ret;
  pcre_config(what, (void *) &ret);
  return ret;
}

/* Generic stub for getting long integer results from pcre_config */
static inline int pcre_config_long(int what)
{
  long ret;
  pcre_config(what, (void *) &ret);
  return ret;
}
コード例 #28
0
/* The bytecode interpreter for the NFA */
static int re_match(value re,
                    unsigned char * starttxt,
                    register unsigned char * txt,
                    register unsigned char * endtxt,
                    int accept_partial_match)
{
  register value * pc;
  intnat instr;
  struct backtrack_stack * stack;
  union backtrack_point * sp;
  value cpool;
  value normtable;
  unsigned char c;
  union backtrack_point back;

  { int i;
    struct re_group * p;
    unsigned char ** q;
    for (p = &re_group[1], i = Numgroups(re); i > 1; i--, p++)
      p->start = p->end = NULL;
    for (q = &re_register[0], i = Numregisters(re); i > 0; i--, q++)
      *q = NULL;
  }

  pc = &Field(Prog(re), 0);
  stack = &initial_stack;
  sp = stack->point;
  cpool = Cpool(re);
  normtable = Normtable(re);
  re_group[0].start = txt;

  while (1) {
    instr = Long_val(*pc++);
    switch (Opcode(instr)) {
    case CHAR:
      if (txt == endtxt) goto prefix_match;
      if (*txt != Arg(instr)) goto backtrack;
      txt++;
      break;
    case CHARNORM:
      if (txt == endtxt) goto prefix_match;
      if (Byte_u(normtable, *txt) != Arg(instr)) goto backtrack;
      txt++;
      break;
    case STRING: {
      unsigned char * s =
        (unsigned char *) String_val(Field(cpool, Arg(instr)));
      while ((c = *s++) != 0) {
        if (txt == endtxt) goto prefix_match;
        if (c != *txt) goto backtrack;
        txt++;
      }
      break;
    }
    case STRINGNORM: {
      unsigned char * s =
        (unsigned char *) String_val(Field(cpool, Arg(instr)));
      while ((c = *s++) != 0) {
        if (txt == endtxt) goto prefix_match;
        if (c != Byte_u(normtable, *txt)) goto backtrack;
        txt++;
      }
      break;
    }
    case CHARCLASS:
      if (txt == endtxt) goto prefix_match;
      if (! In_bitset(String_val(Field(cpool, Arg(instr))), *txt, c))
        goto backtrack;
      txt++;
      break;
    case BOL:
      if (txt > starttxt && txt[-1] != '\n') goto backtrack;
      break;
    case EOL:
      if (txt < endtxt && *txt != '\n') goto backtrack;
      break;
    case WORDBOUNDARY:
      /* At beginning and end of text: no
         At beginning of text: OK if current char is a letter
         At end of text: OK if previous char is a letter
         Otherwise:
           OK if previous char is a letter and current char not a letter
           or previous char is not a letter and current char is a letter */
      if (txt == starttxt) {
        if (txt == endtxt) goto prefix_match;
        if (Is_word_letter(txt[0])) break;
        goto backtrack;
      } else if (txt == endtxt) {
        if (Is_word_letter(txt[-1])) break;
        goto backtrack;
      } else {
        if (Is_word_letter(txt[-1]) != Is_word_letter(txt[0])) break;
        goto backtrack;
      }
    case BEGGROUP: {
      int group_no = Arg(instr);
      struct re_group * group = &(re_group[group_no]);
      back.undo.loc = &(group->start);
      back.undo.val = group->start;
      group->start = txt;
      goto push;
    }
    case ENDGROUP: {
      int group_no = Arg(instr);
      struct re_group * group = &(re_group[group_no]);
      back.undo.loc = &(group->end);
      back.undo.val = group->end;
      group->end = txt;
      goto push;
    }
    case REFGROUP: {
      int group_no = Arg(instr);
      struct re_group * group = &(re_group[group_no]);
      unsigned char * s;
      if (group->start == NULL || group->end == NULL) goto backtrack;
      for (s = group->start; s < group->end; s++) {
        if (txt == endtxt) goto prefix_match;
        if (*s != *txt) goto backtrack;
        txt++;
      }
      break;
    }
    case ACCEPT:
      goto accept;
    case SIMPLEOPT: {
      char * set = String_val(Field(cpool, Arg(instr)));
      if (txt < endtxt && In_bitset(set, *txt, c)) txt++;
      break;
    }
    case SIMPLESTAR: {
      char * set = String_val(Field(cpool, Arg(instr)));
      while (txt < endtxt && In_bitset(set, *txt, c))
        txt++;
      break;
    }
    case SIMPLEPLUS: {
      char * set = String_val(Field(cpool, Arg(instr)));
      if (txt == endtxt) goto prefix_match;
      if (! In_bitset(set, *txt, c)) goto backtrack;
      txt++;
      while (txt < endtxt && In_bitset(set, *txt, c))
        txt++;
      break;
    }
    case GOTO:
      pc = pc + SignedArg(instr);
      break;
    case PUSHBACK:
      back.pos.pc = Set_tag(pc + SignedArg(instr));
      back.pos.txt = txt;
      goto push;
    case SETMARK: {
      int reg_no = Arg(instr);
      unsigned char ** reg = &(re_register[reg_no]);
      back.undo.loc = reg;
      back.undo.val = *reg;
      *reg = txt;
      goto push;
    }
    case CHECKPROGRESS: {
      int reg_no = Arg(instr);
      if (re_register[reg_no] == txt)
        goto backtrack;
      break;
    }
    default:
      caml_fatal_error ("impossible case in re_match");
    }
    /* Continue with next instruction */
    continue;

  push:
    /* Push an item on the backtrack stack and continue with next instr */
    if (sp == stack->point + BACKTRACK_STACK_BLOCK_SIZE) {
      struct backtrack_stack * newstack =
        caml_stat_alloc(sizeof(struct backtrack_stack));
      newstack->previous = stack;
      stack = newstack;
      sp = stack->point;
    }
    *sp = back;
    sp++;
    continue;

  prefix_match:
    /* We get here when matching failed because the end of text
       was encountered. */
    if (accept_partial_match) goto accept;

  backtrack:
    /* We get here when matching fails.  Backtrack to most recent saved
       program point, undoing variable assignments on the way. */
    while (1) {
      if (sp == stack->point) {
        struct backtrack_stack * prevstack = stack->previous;
        if (prevstack == NULL) return 0;
        caml_stat_free(stack);
        stack = prevstack;
        sp = stack->point + BACKTRACK_STACK_BLOCK_SIZE;
      }
      sp--;
      if (Tag_is_set(sp->pos.pc)) {
        pc = Clear_tag(sp->pos.pc);
        txt = sp->pos.txt;
        break;
      } else {
        *(sp->undo.loc) = sp->undo.val;
      }
    }
    continue;
  }

 accept:
  /* We get here when the regexp was successfully matched */
  free_backtrack_stack(stack);
  re_group[0].end = txt;
  return 1;
}
コード例 #29
0
CAMLexport void caml_main(char **argv)
{
  int fd, pos;
  struct exec_trailer trail;
  struct channel * chan;
  value res;
  char * shared_lib_path, * shared_libs, * req_prims;
  char * exe_name;
#ifdef __linux__
  static char proc_self_exe[256];
#endif

  /* Machine-dependent initialization of the floating-point hardware
     so that it behaves as much as possible as specified in IEEE */
  caml_init_ieee_floats();
#ifdef _MSC_VER
  caml_install_invalid_parameter_handler();
#endif
  caml_init_custom_operations();
  caml_ext_table_init(&caml_shared_libs_path, 8);
  caml_external_raise = NULL;
  /* Determine options and position of bytecode file */
#ifdef DEBUG
  caml_verb_gc = 0xBF;
#endif
  parse_camlrunparam();
  pos = 0;
  exe_name = argv[0];
#ifdef __linux__
  if (caml_executable_name(proc_self_exe, sizeof(proc_self_exe)) == 0)
    exe_name = proc_self_exe;
#endif
  fd = caml_attempt_open(&exe_name, &trail, 0);
  if (fd < 0) {
    pos = parse_command_line(argv);
    if (argv[pos] == 0)
      caml_fatal_error("No bytecode file specified.\n");
    exe_name = argv[pos];
    fd = caml_attempt_open(&exe_name, &trail, 1);
    switch(fd) {
    case FILE_NOT_FOUND:
      caml_fatal_error_arg("Fatal error: cannot find file '%s'\n", argv[pos]);
      break;
    case BAD_BYTECODE:
      caml_fatal_error_arg(
        "Fatal error: the file '%s' is not a bytecode executable file\n",
        exe_name);
      break;
    }
  }
  /* Read the table of contents (section descriptors) */
  caml_read_section_descriptors(fd, &trail);
  /* Initialize the abstract machine */
  caml_init_gc (minor_heap_init, heap_size_init, heap_chunk_init,
                percent_free_init, max_percent_free_init);
  caml_init_stack (max_stack_init);
  init_atoms();
  /* Initialize the interpreter */
  caml_interprete(NULL, 0);
  /* Initialize the debugger, if needed */
  caml_debugger_init();
  /* Load the code */
  caml_code_size = caml_seek_section(fd, &trail, "CODE");
  caml_load_code(fd, caml_code_size);
  /* Build the table of primitives */
  shared_lib_path = read_section(fd, &trail, "DLPT");
  shared_libs = read_section(fd, &trail, "DLLS");
  req_prims = read_section(fd, &trail, "PRIM");
  if (req_prims == NULL) caml_fatal_error("Fatal error: no PRIM section\n");
  caml_build_primitive_table(shared_lib_path, shared_libs, req_prims);
  caml_stat_free(shared_lib_path);
  caml_stat_free(shared_libs);
  caml_stat_free(req_prims);
  /* Load the globals */
  caml_seek_section(fd, &trail, "DATA");
  chan = caml_open_descriptor_in(fd);
  caml_global_data = caml_input_val(chan);
  caml_close_channel(chan); /* this also closes fd */
  caml_stat_free(trail.section);
  /* Ensure that the globals are in the major heap. */
  caml_oldify_one (caml_global_data, &caml_global_data);
  caml_oldify_mopup ();
  /* Initialize system libraries */
  caml_init_exceptions();
  caml_sys_init(exe_name, argv + pos);
#ifdef _WIN32
  /* Start a thread to handle signals */
  if (getenv("CAMLSIGPIPE"))
    _beginthread(caml_signal_thread, 4096, NULL);
#endif
  /* Execute the program */
  caml_debugger(PROGRAM_START);
  res = caml_interprete(caml_start_code, caml_code_size);
  if (Is_exception_result(res)) {
    caml_exn_bucket = Extract_exception(res);
    if (caml_debugger_in_use) {
      caml_extern_sp = &caml_exn_bucket; /* The debugger needs the
                                            exception value.*/
      caml_debugger(UNCAUGHT_EXC);
    }
    caml_fatal_uncaught_exception(caml_exn_bucket);
  }
}
コード例 #30
0
CAMLprim value caml_context_split_r(CAML_R, value thread_no_as_value, value function)
{
#if defined(HAS_MULTICONTEXT) //&& defined(NATIVE_CODE)

  //DUMPROOTS("splitting: before GC-protecting locals");
  CAMLparam1(function);
  //CAMLlocal2(result, open_channels);
  CAMLlocal5(result, open_channels, res, tail, chan);
  //DUMPROOTS("splitting: after GC-protecting locals");

  int can_split = caml_can_split_r(ctx);
  if (! can_split)
    caml_raise_cannot_split_r(ctx);

  int thread_no = Int_val(thread_no_as_value);
  caml_global_context **new_contexts = caml_stat_alloc(sizeof(caml_global_context*) * thread_no);
  char *blob;
  sem_t semaphore;
  int i;
  caml_initialize_semaphore(&semaphore, 0);

  /* CAMLparam0(); CAMLlocal1(open_channels); */
  /* Make sure that the currently-existing channels stay alive until
     after deserialization; we can't keep reference counts within the
     blob, so we pin all alive channels by keeping this list alive: */
/* //if(0){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/*   struct channel *channel; */
/*   struct channel **channels; */
/*   int channel_no = 0; */
/*   caml_acquire_global_lock(); */
/*   for (channel = caml_all_opened_channels; */
/*        channel != NULL; */
/*        channel = channel->next) */
/*     channel_no ++; */
/*   channels = caml_stat_alloc(sizeof(struct channel*) * channel_no); */
/*   for (i = 0, channel = caml_all_opened_channels; */
/*        channel != NULL; */
/*        i ++, channel = channel->next){ */
/*     channels[i] = channel; */
/*     DUMP("split-pinning channel %p, with fd %i, refcount %i->%i", channel, (int)channel->fd, channel->refcount, channel->refcount + 1); */
/*     channel->refcount ++; */
/*   } */
/*   caml_release_global_lock(); */

  //open_channels = caml_ml_all_channels_list_r(ctx); // !!!!!!!!!!!!!!!!!!!! This can occasionally cause crashes related to channel picounts.  I certainly messed up something in io.c. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//}//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/* //EXPERIMENTAL: BEGIN */
/* { */
/*   struct channel * channel; */

/*   res = Val_emptylist; */
/* caml_acquire_global_lock(); */
/*  int ii, channel_index; */
/*  for(ii = 0; ii < 100; ii ++){ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/*   for (channel_index = 0, channel = caml_all_opened_channels; */
/*        channel != NULL; */
/*        channel = channel->next, channel_index ++) */
/*     /\* Testing channel->fd >= 0 looks unnecessary, as */
/*        caml_ml_close_channel changes max when setting fd to -1. *\/ */
/*     { */
/*       DUMP("round %i, channel_index %i", ii, channel_index); */
/*       // !!!!!!!!!!!!! BEGIN */
/*       /\* chan = *\/ caml_alloc_channel_r (ctx, channel); */
/*       // !!!!!!!!!!!!! END */
/*       chan = Val_unit;//caml_alloc_channel_r (ctx, channel); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/*       tail = res; */
/*       res = caml_alloc_small_r (ctx, 2, 0); */
/*       Field (res, 0) = chan; */
/*       Field (res, 1) = tail; */
/*     } */
/*   DUMP("End of round %i: there are %i channels alive", ii, channel_index); */
/*   DUMP("Before GC'ing"); */
/*   caml_gc_compaction_r(ctx, Val_unit); //!!!!!@@@@@@@@@@@@@ */
/*   DUMP("After GC'ing"); */
/*  } */
/* caml_release_global_lock(); */
/*   //open_channels = Val_unit/\* res *\/; */
/*   open_channels = res; */
/* } */
/* //EXPERIMENTAL: END */

  /* Serialize the context in the main thread, then create threads,
     and in each one of them deserialize it back in parallel:  */
  blob = caml_serialize_context(ctx, function);
  //if(0){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  caml_split_and_wait_r(ctx, blob, new_contexts, thread_no, &semaphore);
  //}//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  /* Now we're done with the blob: */
  DUMP("destroying the blob");
  caml_stat_free(blob); // !!!!!!!!!!!!!!!!!!!!!!!!!!! This is needed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  DUMP("GC'ing after destroying the blob");
  caml_gc_compaction_r(ctx, Val_unit); //!!!!!@@@@@@@@@@@@@
  DUMP("finalizing the semaphore");

  caml_finalize_semaphore(&semaphore);

  /* Copy the contexts we got, and we're done with new_contexts as well: */
  DUMP("copying the new context (descriptors) into the Caml data structure result");
  result = caml_alloc_r(ctx, thread_no, 0);
  caml_gc_compaction_r(ctx, Val_unit); //!!!!!@@@@@@@@@@@@
  for(i = 0; i < thread_no; i ++)
    caml_initialize_r(ctx, &Field(result, i), caml_value_of_context_descriptor(new_contexts[i]->descriptor));
  caml_stat_free(new_contexts);
  DUMP("destroyed the malloced buffer of pointers new_contexts");
  //DUMPROOTS("from parent, after splitting");

  /* caml_acquire_global_lock(); */
  /* for (i = 0; i < channel_no; i ++){ */
  /*   DUMP("split-unpinning channels[i] %p, with fd %i, refcount %i->%i", channels[i], (int)channels[i]->fd, channels[i]->refcount, channels[i]->refcount - 1); */
  /*   channels[i]->refcount --; */
  /* } */
  /* caml_release_global_lock(); */

  CAMLreturn(result);
  //CAMLreturn(Val_unit);
#else
  caml_raise_unimplemented_r(ctx);
  return Val_unit; // unreachable
#endif // #if defined(HAS_MULTICONTEXT) //&& defined(NATIVE_CODE)
}