/* Return 0 on success and non-zero on failure. */
static int caml_run_function_this_thread_r(CAML_R, value function, int index)
{
  CAMLparam1(function);
  CAMLlocal1(result_or_exception);
  int did_we_fail;

/* fprintf(stderr, "======Forcing a GC\n"); fflush(stderr); */
//caml_gc_compaction_r(ctx, Val_unit); //!!!!!
/* fprintf(stderr, "======It's ok to have warnings about the lack of globals up to this point\n"); fflush(stderr); */

//fprintf(stderr, "W0[context %p] [thread %p] (index %i) BBBBBBBBBBBBBBBBBBBBBBBBBB\n", ctx, (void*)(pthread_self()), index); fflush(stderr); caml_acquire_global_lock(); // FIXME: a test. this is obviously unusable in production
//fprintf(stderr, "W1 [context %p] ctx->caml_local_roots is %p\n", ctx, caml_local_roots); fflush(stderr);
//DUMP();
  /* Make a new context, and deserialize the blob into it: */
  /* fprintf(stderr, "W3 [context %p] [thread %p] (index %i) (function %p)\n", ctx, (void*)(pthread_self()), index, (void*)function); fflush(stderr); */

  /* // Allocate some trash: */
  /* caml_pair_r(ctx, */
  /*             caml_pair_r(ctx, Val_int(1), Val_int(2)), */
  /*             caml_pair_r(ctx, Val_int(3), Val_int(4))); */

 //fprintf(stderr, "W4 [context %p] [thread %p] (index %i) (function %p)\n", ctx, (void*)(pthread_self()), index, (void*)function); fflush(stderr);
//caml_gc_compaction_r(ctx, Val_unit); //!!!!!
  //DUMP();

/* caml_empty_minor_heap_r(ctx); */
/* caml_finish_major_cycle_r (ctx); */
/* caml_compact_heap_r (ctx); */
/* caml_final_do_calls_r (ctx); */

  /* Run the Caml function: */
 //fprintf(stderr, "W5 [context %p] [thread %p] (index %i) (function %p)\n", ctx, (void*)(pthread_self()), index, (void*)function); fflush(stderr);
  //caml_gc_compaction_r(ctx, Val_unit); //!!!!!
  //DUMP();
  //fprintf(stderr, "W7 [context %p] [thread %p] (index %i) (%i globals) ctx->caml_local_roots is %p\n", ctx, (void*)(pthread_self()), index, (int)(ctx->caml_globals.used_size / sizeof(value)), caml_local_roots); fflush(stderr);
  //caml_dump_global_mutex();

  /* It's important that Extract_exception be used before the next
     collection, because result_or_exception is an invalid value in
     case of exception: */
  DUMP("running caml code in the new context");
  result_or_exception = caml_callback_exn_r(ctx, function, Val_int(index));
  did_we_fail = Is_exception_result(result_or_exception);
  result_or_exception = Extract_exception(result_or_exception);
  //caml_enter_blocking_section_r(ctx); // !!!!!!!!!!!!!!!
  caml_enter_blocking_section_r(ctx); // Allow threads created by function to obtain the CPU
  DUMP("back from the caml code in the new context");
  /* If we decide to actually do something with result_or_exception,
     then it becomes important that we call Extract_exception on it
     (when it's an exception) before the next Caml allocation: in case
     of exception result_or_exception is an invalid value, messing up
     the GC. */
  did_we_fail = Is_exception_result(result_or_exception);
  if(did_we_fail){
    char *printed_exception = caml_format_exception_r(ctx, result_or_exception);
    fprintf(stderr, "FAILED with the exception %s\n", printed_exception); fflush(stderr);
    free(printed_exception);
  }
  CAMLreturnT(int, did_we_fail);
}
Beispiel #2
0
void caml_execute_signal(int signal_number, int in_signal_handler)
{
  value res;
#ifdef POSIX_SIGNALS
  sigset_t sigs;
  /* Block the signal before executing the handler, and record in sigs
     the original signal mask */
  sigemptyset(&sigs);
  sigaddset(&sigs, signal_number);
  sigprocmask(SIG_BLOCK, &sigs, &sigs);
#endif
  res = caml_callback_exn(
           Field(caml_signal_handlers, signal_number),
           Val_int(caml_rev_convert_signal_number(signal_number)));
#ifdef POSIX_SIGNALS
  if (! in_signal_handler) {
    /* Restore the original signal mask */
    sigprocmask(SIG_SETMASK, &sigs, NULL);
  } else if (Is_exception_result(res)) {
    /* Restore the original signal mask and unblock the signal itself */
    sigdelset(&sigs, signal_number);
    sigprocmask(SIG_SETMASK, &sigs, NULL);
  }
#endif
  if (Is_exception_result(res)) caml_raise(Extract_exception(res));
}
Beispiel #3
0
CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
{
  CAMLparam1 (closure);
  CAMLxparamN (args, narg);
  CAMLlocal1 (res);
  int i;

  res = closure;
  for (i = 0; i < narg; /*nothing*/) {
    /* Pass as many arguments as possible */
    switch (narg - i) {
    case 1:
      res = caml_callback_exn(res, args[i]);
      if (Is_exception_result(res)) CAMLreturn (res);
      i += 1;
      break;
    case 2:
      res = caml_callback2_exn(res, args[i], args[i + 1]);
      if (Is_exception_result(res)) CAMLreturn (res);
      i += 2;
      break;
    default:
      res = caml_callback3_exn(res, args[i], args[i + 1], args[i + 2]);
      if (Is_exception_result(res)) CAMLreturn (res);
      i += 3;
      break;
    }
  }
  CAMLreturn (res);
}
Beispiel #4
0
CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
{
  CAMLparam0();
  struct stack_info* parent_stack;
  int i;
  value res;
  caml_domain_state* domain_state = Caml_state;
  parent_stack = Stack_parent(domain_state->current_stack);
  Stack_parent(domain_state->current_stack) = NULL;

  CAMLassert(narg + 4 <= 256);
  domain_state->current_stack->sp -= narg + 4;
  for (i = 0; i < narg; i++) domain_state->current_stack->sp[i] = args[i]; /* arguments */

  opcode_t code[7] = {
    callback_code[0], narg + 3,
    callback_code[2], narg,
    callback_code[4], callback_code[5], callback_code[6]
  };

  domain_state->current_stack->sp[narg] = Val_pc (code + 4); /* return address */
  domain_state->current_stack->sp[narg + 1] = Val_unit;    /* environment */
  domain_state->current_stack->sp[narg + 2] = Val_long(0); /* extra args */
  domain_state->current_stack->sp[narg + 3] = closure;
  res = caml_interprete(code, sizeof(code));
  if (Is_exception_result(res)) domain_state->current_stack->sp += narg + 4; /* PR#1228 */

  Assert(Stack_parent(domain_state->current_stack) == NULL);
  Stack_parent(domain_state->current_stack) = parent_stack;
  CAMLreturn (res);
}
Beispiel #5
0
CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
{
  CAMLparam0();
  CAMLlocal1(parent_stack);
  int i;
  value res;
  parent_stack = Stack_parent(caml_current_stack);
  Stack_parent(caml_current_stack) = Val_unit;

  Assert(narg + 4 <= 256);
  caml_extern_sp -= narg + 4;
  for (i = 0; i < narg; i++) caml_extern_sp[i] = args[i]; /* arguments */

  opcode_t code[7] = {
    callback_code[0], narg + 3,
    callback_code[2], narg,
    callback_code[4], callback_code[5], callback_code[6]
  };

  caml_extern_sp[narg] = Val_pc (code + 4); /* return address */
  caml_extern_sp[narg + 1] = Val_unit;    /* environment */
  caml_extern_sp[narg + 2] = Val_long(0); /* extra args */
  caml_extern_sp[narg + 3] = closure;
  res = caml_interprete(code, sizeof(code));
  if (Is_exception_result(res)) caml_extern_sp += narg + 4; /* PR#1228 */

  Assert(Stack_parent(caml_current_stack) == Val_unit);
  Stack_parent(caml_current_stack) = parent_stack;
  CAMLreturn (res);
}
Beispiel #6
0
static inline int exec_not_null_callback(
  void *cbx_, int num_columns, char **row, char **header)
{
  callback_with_exn *cbx = cbx_;
  value v_row, v_header, v_ret;

  caml_leave_blocking_section();

    v_row = copy_not_null_string_array((const char **) row, num_columns);

    if (v_row == (value) NULL) return 1;

    Begin_roots1(v_row);
      v_header = safe_copy_string_array((const char **) header, num_columns);
    End_roots();

    v_ret = caml_callback2_exn(*cbx->cbp, v_row, v_header);

    if (Is_exception_result(v_ret)) {
      *cbx->exn = Extract_exception(v_ret);
      caml_enter_blocking_section();
      return 1;
    }

  caml_enter_blocking_section();

  return 0;
}
Beispiel #7
0
void caml_startup(char_os **argv)
{
  value res = caml_startup_exn(argv);
  caml_maybe_print_stats(Val_unit);
  if (Is_exception_result(res))
    caml_fatal_uncaught_exception(Extract_exception(res));
}
Beispiel #8
0
herr_t hdf5_h5l_operator(hid_t group, const char *name, const H5L_info_t *info,
  void *op_data)
{
  CAMLparam0();
  CAMLlocal5(ret, info_v, address_v, args0, args1);
  CAMLlocal2(args2, args3);
  value args[4];

  struct operator_data *operator_data = op_data;
  args0 = alloc_h5l(group);
  args1 = caml_copy_string(name);
  args2 = Val_h5l_info(info);
  args3 = *operator_data->operator_data;
  args[0] = args0;
  args[1] = args1;
  args[2] = args2;
  args[3] = args3;
  ret = caml_callbackN_exn(*operator_data->callback, 4, args);
  if (Is_exception_result(ret))
  {
    *(operator_data->exception) = Extract_exception(ret);
    return -1;
  }
  CAMLreturnT(herr_t, H5_iter_val(ret));
}
Beispiel #9
0
// Called by the host app to configure miTLS ahead of creating a connection
int FFI_mitls_configure(mitls_state **state, const char *tls_version, const char *host_name, char **outmsg, char **errmsg)
{
    CAMLparam0();
    CAMLlocal3(config, version, host);
    int ret = 0;

    *state = NULL;
    *outmsg = NULL;
    *errmsg = NULL;
    
    version = caml_copy_string(tls_version);  
    host = caml_copy_string(host_name);
    caml_acquire_runtime_system();
    config = caml_callback2_exn(*g_mitls_FFI_Config, version, host);
    if (Is_exception_result(config)) {
        // call caml_format_exception(Extract_exception(config)) to extract the exception information
    } else {
        mitls_state * s;
        
        // Allocate space on the heap, to store an OCaml value
        s = (mitls_state*)malloc(sizeof(mitls_state));
        if (s) {
            // Tell the OCaml GC about the heap address, so it is treated
            // as a GC root, keeping the config object live.
            s->fstar_state = config; 
            caml_register_generational_global_root(&s->fstar_state);
            *state = s;
            ret = 1;
        }
    }
    caml_release_runtime_system();

    CAMLreturnT(int,ret);
}
Beispiel #10
0
// Called by the host app to create a TLS connection.
int FFI_mitls_connect(struct _FFI_mitls_callbacks *callbacks, /* in */ mitls_state *state, /* out */ char **outmsg, /* out */ char **errmsg)
{
    CAMLparam0();
    CAMLlocal1(result);
    int ret;
    
    *outmsg = NULL;
    *errmsg = NULL;
    
    caml_acquire_runtime_system();
    result = caml_callback2_exn(*g_mitls_FFI_Connect, state->fstar_state, PtrToValue(callbacks));
    if (Is_exception_result(result)) {
        // Call caml_format_exception(Extract_exception(result)) to extract the exception text
        ret = 0;
    } else {
        // Connect returns back (Connection.connection * int)
        value connection = Field(result,0);
        ret = Int_val(Field(result,1));
        if (ret == 0) {
            caml_modify_generational_global_root(&state->fstar_state, connection);
            ret = 1;
        } else {
            ret = 0;
        }
        // The result is an integer.  How to deduce the value of 'c' needed for
        // subsequent FFI.read and FFI.write is TBD.
        
    }
    caml_release_runtime_system();
    CAMLreturnT(int,ret);
}
Beispiel #11
0
int cstr_post(value* in)
{
  value v;
  CLOSURE ("Cstr.post");
  v = caml_callback_exn(*closure, *in);
  return Is_exception_result(v);
}
Beispiel #12
0
CAMLexport value caml_callback3 (value closure, value arg1, value arg2,
                                 value arg3)
{
  value res = caml_callback3_exn(closure, arg1, arg2, arg3);
  if (Is_exception_result(res)) caml_raise(Extract_exception(res));
  return res;
}
Beispiel #13
0
/* Do a minor collection and a slice of major collection, call finalisation
   functions, etc.
   Leave the minor heap empty.
*/
CAMLexport void caml_minor_collection (void)
{
  value *note_gc;
  uint64_t start_time;

  note_gc = caml_named_value("MProf.Trace.note_gc");
  if (note_gc)
    start_time = NOW();

  intnat prev_alloc_words = caml_allocated_words;

  caml_empty_minor_heap ();

  caml_stat_promoted_words += caml_allocated_words - prev_alloc_words;
  ++ caml_stat_minor_collections;
  caml_major_collection_slice (0);
  caml_force_major_slice = 0;

  caml_final_do_calls ();

  if (note_gc){
    double duration_ns = (double) (NOW () - start_time);
    value result = caml_callback_exn(*note_gc, caml_copy_double(duration_ns / 1000000000));
    if (Is_exception_result(result))
      printk("warning: note_gc threw an exception!\n");
  }

  caml_empty_minor_heap ();
}
Beispiel #14
0
static int putc_callback(int c)
{
  CAMLparam0();
  CAMLlocal1(ret);

  AWB(ret);
  ret=callback_exn(putc_function,Val_int(c&255));
  CAMLreturn(Is_exception_result(ret)?-1:0);
}
Beispiel #15
0
static gboolean ml_gtk_text_char_predicate(gunichar ch, gpointer user_data)
{
  value res, *clos = user_data;
  res = callback_exn (*clos, Val_int(ch));
  if (Is_exception_result (res)) {
    CAML_EXN_LOG ("ml_gtk_text_char_predicate");
    return FALSE;
  }
  return Bool_val(res);
}
Beispiel #16
0
static
void ml_rsvg_size_callback(gint *w, gint *h, gpointer user_data)
{
  value *cb = user_data;
  value r;
  r = callback2_exn(*cb, Val_int(*w), Val_int(*h));
  if(Is_exception_result(r)) return;
  *w = Int_val(Field(r, 0));
  *h = Int_val(Field(r, 1));
}
Beispiel #17
0
int range_set_exception(value caml_result) {
  if (Is_exception_result(caml_result)) {
    if (ocaml_exception) free(ocaml_exception);
    ocaml_exception = strdup(String_val(Field(Extract_exception(caml_result), 1)));
    return 1;
  } else {
    range_clear_exception();
    return 0;
  }
}
Beispiel #18
0
static void timer_proc(ClientData cdata) {
    timerhandler *h;
    value r;
    
    h = (timerhandler *) cdata;

    r = callback_exn(h->callback_fn, Val_int(0));
    if (Is_exception_result(r)) {
	fprintf(stderr, "In timer_proc: Uncaught Ocaml exception\n");
    };
}
Beispiel #19
0
static void file_proc(ClientData cdata, int mask) {
    filehandler *h;
    value r;
    
    h = (filehandler *) cdata;

    r = callback_exn(h->callback_fn, Val_int(0));
    if (Is_exception_result(r)) {
	fprintf(stderr, "In file_proc: Uncaught Ocaml exception\n");
    };
}
Beispiel #20
0
Hunpos hunpos_tagger_new(const char* model_file, const char* morph_table_file, int max_guessed_tags, int theta, int* error)
{
    *error = 0;
    if(model_file == NULL) {
	*error = 3;
	return NULL;
    }
    if(morph_table_file == NULL) {
	morph_table_file = "";
    }

    /* Startup OCaml */
    if (is_initialized == 0)
    {
	is_initialized = 1;
	char* dummyargv[2];
	dummyargv[0]="";
	dummyargv[1]=NULL;
	caml_startup(dummyargv);
    }
    CAMLparam0();

    /* get hunpos init function from ocaml */
     static value* init_fun;
     if (init_fun == NULL)
     {
           init_fun = caml_named_value("init_from_files");
     }

     Hunpos tagger_fun = (Hunpos) malloc(sizeof(value));
     *((value*)tagger_fun) = 0;

     // we pass some argument to the function
     CAMLlocalN ( args, 4 );
     args[0] = caml_copy_string(model_file);
     args[1] = caml_copy_string(morph_table_file);
     args[2] = Val_int(max_guessed_tags);
     args[3] = Val_int(theta);

     /* due to the garbage collector we have to register the */
     /* returned value not to be deallocated                 */
     caml_register_global_root(tagger_fun);
     value* t = tagger_fun;
     *t =  caml_callbackN_exn( *init_fun, 4, args );
     if (Is_exception_result(*t))
     {
	*error = 1;
	CAMLreturnT(Hunpos, NULL);
     }

     // CAMLreturn1(tagger_fun)
     CAMLreturnT(Hunpos,tagger_fun);

  }
Beispiel #21
0
cairo_status_t
ml_cairo_unsafe_read_func (void *closure, unsigned char *data, unsigned int length)
{
  value res, *c = closure;
  res = caml_callback2_exn (Field (*c, 0), Val_bp (data), Val_int (length));
  if (Is_exception_result (res))
    {
      Store_field (*c, 1, res);
      return CAIRO_STATUS_READ_ERROR;
    }
  return CAIRO_STATUS_SUCCESS;
}
Beispiel #22
0
static int ml_gsl_odeiv_func(double t, const double y[], 
			     double dydt[], void *params)
{
  struct mlgsl_odeiv_params *p = params;
  value vt, res;
  vt  = copy_double(t);
  memcpy(Double_array_val(p->arr1), y, p->dim * sizeof(double));
  res = callback3_exn(p->closure, vt, p->arr1, p->arr2);
  if(Is_exception_result(res))
    return GSL_FAILURE;
  memcpy(dydt, Double_array_val(p->arr2), p->dim * sizeof(double));
  return GSL_SUCCESS;
}
static N_Vector callml_custom_resid(SUNLinearSolver ls)
{
    CAMLparam0();
    CAMLlocal1(r);

    r = caml_callback_exn(GET_OP(ls, GET_RES_ID), Val_unit);
    if (Is_exception_result (r)) {
	sunml_warn_discarded_exn (Extract_exception (r),
					"user-defined res id handler");
	CAMLreturnT(N_Vector, NULL);
    }

    CAMLreturnT(N_Vector, NVEC_VAL(r));
}
static realtype callml_custom_resnorm(SUNLinearSolver ls)
{
    CAMLparam0();
    CAMLlocal1(r);

    r = caml_callback_exn(GET_OP(ls, GET_RES_NORM), Val_unit);
    if (Is_exception_result (r)) {
	sunml_warn_discarded_exn (Extract_exception (r),
					"user-defined res norm handler");
	CAMLreturnT(realtype, 0.0);
    }

    CAMLreturnT(realtype, Double_val(r));
}
Beispiel #25
0
cairo_status_t
ml_cairo_read_func (void *closure, unsigned char *data, unsigned int length)
{
  value s, res, *c = closure;
  s = caml_alloc_string (length);
  res = caml_callback_exn (Field (*c, 0), s);
  if (Is_exception_result (res))
    {
      Store_field (*c, 1, res);
      return CAIRO_STATUS_READ_ERROR;
    }
  memcpy (data, String_val (s), length);
  return CAIRO_STATUS_SUCCESS;
}
Beispiel #26
0
/* Callout handler */
static int pcre_callout_handler(pcre_callout_block* cb)
{
  struct cod *cod = (struct cod *) cb->callout_data;

  if (cod != NULL) {
    /* Callout is available */
    value v_res;

    /* Set up parameter array */
    value v_callout_data = caml_alloc_small(6, 0);

    const value v_substrings = *cod->v_substrings_p;

    const int capture_top = cb->capture_top;
    int subgroups2 = capture_top << 1;
    const int subgroups2_1 = subgroups2 - 1;

    const int *ovec_src = cb->offset_vector + subgroups2_1;
    long int *ovec_dst = &Field(Field(v_substrings, 1), 0) + subgroups2_1;

    /* Copy preliminary substring information */
    while (subgroups2--) {
      *ovec_dst = Val_int(*ovec_src);
      --ovec_src; --ovec_dst;
    }

    Field(v_callout_data, 0) = Val_int(cb->callout_number);
    Field(v_callout_data, 1) = v_substrings;
    Field(v_callout_data, 2) = Val_int(cb->start_match);
    Field(v_callout_data, 3) = Val_int(cb->current_position);
    Field(v_callout_data, 4) = Val_int(capture_top);
    Field(v_callout_data, 5) = Val_int(cb->capture_last);
    Field(v_callout_data, 6) = Val_int(cb->pattern_position);
    Field(v_callout_data, 7) = Val_int(cb->next_item_length);

    /* Perform callout */
    v_res = caml_callback_exn(*cod->v_cof_p, v_callout_data);

    if (Is_exception_result(v_res)) {
      /* Callout raised an exception */
      const value v_exn = Extract_exception(v_res);
      if (Field(v_exn, 0) == *pcre_exc_Backtrack) return 1;
      cod->v_exn = v_exn;
      return PCRE_ERROR_CALLOUT;
    }
  }

  return 0;
}
Beispiel #27
0
void caml_main(char **argv)
{
  char * exe_name;
#ifdef __linux__
  static char proc_self_exe[256];
#endif
  value res;
  char tos;

  caml_init_ieee_floats();
#ifdef _MSC_VER
  caml_install_invalid_parameter_handler();
#endif
  caml_init_custom_operations();
#ifdef DEBUG
  caml_verb_gc = 63;
#endif
  caml_top_of_stack = &tos;
  parse_camlrunparam();
  caml_init_gc (minor_heap_init, heap_size_init, heap_chunk_init,
                percent_free_init, max_percent_free_init);
  init_atoms();
  caml_init_signals();
#if !defined(__FreeBSD__) && !defined(_KERNEL)
  caml_debugger_init (); /* force debugger.o stub to be linked */
#endif
  exe_name = argv[0];
  if (exe_name == NULL) exe_name = "";
#ifdef __linux__
  if (caml_executable_name(proc_self_exe, sizeof(proc_self_exe)) == 0)
    exe_name = proc_self_exe;
  else
    exe_name = caml_search_exe_in_path(exe_name);
#elif defined(__FreeBSD__) && defined(_KERNEL)
  exe_name = "mirage.ko";
#else
  exe_name = caml_search_exe_in_path(exe_name);
#endif
  caml_sys_init(exe_name, argv);
  if (sigsetjmp(caml_termination_jmpbuf.buf, 0)) {
    if (caml_termination_hook != NULL) caml_termination_hook(NULL);
    return;
  }
  res = caml_start_program();
  if (Is_exception_result(res))
    caml_fatal_uncaught_exception(Extract_exception(res));
}
Beispiel #28
0
void IDAOCaml_invoke_hotkey_callback(int i)
{
  CAMLlocal1(ret);

  ret = caml_callback_exn(*caml_named_value("HotkeyCallback"), Val_int(i));
  if(Is_exception_result(ret))
  {
    char buf[1024];
    char *exn = caml_format_exception(Extract_exception(ret));
    sprintf(buf, "[E] Function bound to hotkey (internal %d) threw exception (value %08lx): %s\n", 
      i, 
      Extract_exception(ret), 
      exn);
    wrap_msg(buf);
    free(exn);
  }
}
Beispiel #29
0
static void
event_callback_wrapper_locked (guestfs_h *g,
                               void *data,
                               uint64_t event,
                               int event_handle,
                               int flags,
                               const char *buf, size_t buf_len,
                               const uint64_t *array, size_t array_len)
{
  CAMLparam0 ();
  CAMLlocal5 (gv, evv, ehv, bufv, arrayv);
  CAMLlocal2 (rv, v);
  value *root;
  size_t i;

  root = guestfs_get_private (g, "_ocaml_g");
  gv = *root;

  /* Only one bit should be set in 'event'.  Which one? */
  evv = Val_int (event_bitmask_to_event (event));

  ehv = Val_int (event_handle);

  bufv = caml_alloc_string (buf_len);
  memcpy (String_val (bufv), buf, buf_len);

  arrayv = caml_alloc (array_len, 0);
  for (i = 0; i < array_len; ++i) {
    v = caml_copy_int64 (array[i]);
    Store_field (arrayv, i, v);
  }

  value args[5] = { gv, evv, ehv, bufv, arrayv };

  rv = caml_callbackN_exn (*(value*)data, 5, args);

  /* Callbacks shouldn't throw exceptions.  There's not much we can do
   * except to print it.
   */
  if (Is_exception_result (rv))
    fprintf (stderr,
             "libguestfs: uncaught OCaml exception in event callback: %s",
             caml_format_exception (Extract_exception (rv)));

  CAMLreturn0;
}
Beispiel #30
0
CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
{
  int i;
  value res;

  /* some alternate bytecode implementations (e.g. a JIT translator)
     might require that the bytecode is kept in a local variable on
     the C stack */
#ifdef LOCAL_CALLBACK_BYTECODE
  opcode_t local_callback_code[7];
#endif

  Assert(narg + 4 <= 256);

  caml_extern_sp -= narg + 4;
  for (i = 0; i < narg; i++) caml_extern_sp[i] = args[i]; /* arguments */
#ifndef LOCAL_CALLBACK_BYTECODE
  caml_extern_sp[narg] = (value) (callback_code + 4); /* return address */
  caml_extern_sp[narg + 1] = Val_unit;    /* environment */
  caml_extern_sp[narg + 2] = Val_long(0); /* extra args */
  caml_extern_sp[narg + 3] = closure;
  Init_callback();
  callback_code[1] = narg + 3;
  callback_code[3] = narg;
  res = caml_interprete(callback_code, sizeof(callback_code));
#else /*have LOCAL_CALLBACK_BYTECODE*/
  caml_extern_sp[narg] = (value) (local_callback_code + 4); /* return address */
  caml_extern_sp[narg + 1] = Val_unit;    /* environment */
  caml_extern_sp[narg + 2] = Val_long(0); /* extra args */
  caml_extern_sp[narg + 3] = closure;
  local_callback_code[0] = ACC;
  local_callback_code[1] = narg + 3;
  local_callback_code[2] = APPLY;
  local_callback_code[3] = narg;
  local_callback_code[4] = POP;
  local_callback_code[5] =  1;
  local_callback_code[6] = STOP;
#ifdef THREADED_CODE
  caml_thread_code(local_callback_code, sizeof(local_callback_code));
#endif /*THREADED_CODE*/
  res = caml_interprete(local_callback_code, sizeof(local_callback_code));
  caml_release_bytecode(local_callback_code, sizeof(local_callback_code));
#endif /*LOCAL_CALLBACK_BYTECODE*/
  if (Is_exception_result(res)) caml_extern_sp += narg + 4; /* PR#1228 */
  return res;
}