Beispiel #1
0
static VALUE strongtyping_get_arg_types(VALUE obj UNUSED, VALUE method) {
  VALUE query, ary;
  query = rb_funcall(cQueryParams, rb_intern("new"), 0);
  ary   = rb_ary_new3(2, method, query);
    
  return rb_rescue2(call_method, ary, grab_types, query, eArgList, 0);
}
Beispiel #2
0
/*
 * Removes a file or directory, using File.unlink if +self+ is a file, or
 * Dir.unlink as necessary.
 */
static VALUE
path_unlink(VALUE self)
{
    VALUE eENOTDIR = rb_const_get_at(rb_mErrno, rb_intern("ENOTDIR"));
    VALUE str = get_strpath(self);
    return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0);
}
Beispiel #3
0
static VALUE
lazy_zip_func(VALUE val, VALUE zip_args, int argc, VALUE *argv)
{
    VALUE yielder, ary, arg, v;
    long i;

    yielder = argv[0];
    arg = rb_attr_get(yielder, id_memo);
    if (NIL_P(arg)) {
	arg = rb_ary_new2(RARRAY_LEN(zip_args));
	for (i = 0; i < RARRAY_LEN(zip_args); i++) {
	    rb_ary_push(arg, rb_funcall(RARRAY_AREF(zip_args, i), id_to_enum, 0));
	}
	rb_ivar_set(yielder, id_memo, arg);
    }

    ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
    rb_ary_push(ary, argv[1]);
    for (i = 0; i < RARRAY_LEN(arg); i++) {
	v = rb_rescue2(call_next, RARRAY_AREF(arg, i), next_stopped, 0,
		       rb_eStopIteration, (VALUE)0);
	rb_ary_push(ary, v);
    }
    rb_funcall(yielder, id_yield, 1, ary);
    return Qnil;
}
Beispiel #4
0
void
shoes_canvas_paint(VALUE self)
{
  rb_rescue2(CASTHOOK(shoes_canvas_paint_call), self, 
    CASTHOOK(shoes_canvas_error), self, rb_cObject, 0);
  return;
}
Beispiel #5
0
VALUE
rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
	  VALUE (* r_proc)(ANYARGS), VALUE data2)
{
    return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
		      (VALUE)0);
}
Beispiel #6
0
static VALUE
cr_user_font_face_invoke_func (VALUE user_data)
{
  return rb_rescue2 (cr_user_font_face_invoke_body, user_data,
                     cr_user_font_face_invoke_rescue, user_data, rb_eException,
                     (VALUE)0);
}
Beispiel #7
0
/* call-seq:
 *    client.query(sql, options = {})
 *
 * Query the database with +sql+, with optional +options+.  For the possible
 * options, see default_query_options on the Mysql2::Client class.
 */
static VALUE rb_query(VALUE self, VALUE sql, VALUE current) {
#ifndef _WIN32
  struct async_query_args async_args;
#endif
  struct nogvl_send_query_args args;
  GET_CLIENT(self);

  REQUIRE_CONNECTED(wrapper);
  args.mysql = wrapper->client;

  (void)RB_GC_GUARD(current);
  Check_Type(current, T_HASH);
  rb_iv_set(self, "@current_query_options", current);

  Check_Type(sql, T_STRING);
#ifdef HAVE_RUBY_ENCODING_H
  /* ensure the string is in the encoding the connection is expecting */
  args.sql = rb_str_export_to_enc(sql, rb_to_encoding(wrapper->encoding));
#else
  args.sql = sql;
#endif
  args.sql_ptr = RSTRING_PTR(args.sql);
  args.sql_len = RSTRING_LEN(args.sql);
  args.wrapper = wrapper;

  rb_mysql_client_set_active_thread(self);

#ifndef _WIN32
  rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);

  if (rb_hash_aref(current, sym_async) == Qtrue) {
    return Qnil;
  } else {
    async_args.fd = wrapper->client->net.fd;
    async_args.self = self;

    rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0);

    return rb_mysql_client_async_result(self);
  }
#else
  do_send_query(&args);

  /* this will just block until the result is ready */
  return rb_ensure(rb_mysql_client_async_result, self, finish_and_mark_inactive, self);
#endif
}
Beispiel #8
0
VALUE rh_safe_call(const char *description, rh_function process_function, VALUE arg)
{
  return rb_rescue2(
    process_function, arg,
    (rh_function)rh_safe_call_failed, (VALUE)description,
    rb_eException, (VALUE)0
  );
}
Beispiel #9
0
VALUE NS(Rescue) (
  struct MqS * const  mqctx,
  VALUE(*proc)(ANYARGS),
  VALUE data
)
{ 
  return rb_rescue2(proc, data, sRescueError, SELF, rb_eException, (VALUE)0);
}
Beispiel #10
0
VALUE
rb_protect(VALUE (*proc) (VALUE), VALUE data, int *state)
{
    if (state != NULL) {
	*state = 0;
    }
    return rb_rescue2(proc, data, protect_rescue, (VALUE)state,
	    rb_eStandardError, (VALUE)0);
}
static bool compile_script_rb(language_t*li, const char*script)
{
    log_dbg("[ruby] compile_script");
    ruby_dfunc_t dfunc;
    dfunc.li = li;
    dfunc.script = script;
    dfunc.fail = false;
    volatile VALUE ret = rb_rescue2(compile_script_internal, (VALUE)&dfunc, compile_script_exception, (VALUE)&dfunc, rb_eException, (VALUE)0);
    return !dfunc.fail;
}
static VALUE
cr_surface_invoke_io_func (VALUE user_data)
{
  cr_invoke_data_t *data;

  data = (cr_invoke_data_t *)user_data;
  return rb_rescue2 (data->func, data->data,
                     cr_surface_io_func_rescue, data->data, rb_eException,
                     (VALUE)0);
}
 inline void rescue(RetT* out)
 {
     auto f1 = rescue_begin_body<RetT, Func>;
     auto f2 = rescue_rescue_block;
     void* data[1];
     data[0] = reinterpret_cast<void*>(out);
     VALUE ex = Qnil;
     rb_rescue2((VALUE(*)(...))f1, (VALUE)data, (VALUE(*)(...))f2, (VALUE)&ex, rb_eException, 0);
     if (ex != Qnil)
         throw Exception(ex);
 }
Beispiel #14
0
VALUE
rb_require_safe(VALUE fname, int safe)
{
    FilePathValue(fname);

    // Immediately, check out if we have an AOT feature for this.
    if (rb_vm_aot_feature_load(RSTRING_PTR(fname))) {
	rb_provide_feature(fname);
	return Qtrue;
    }

#if MACRUBY_STATIC
    rb_raise(rb_eRuntimeError, "#require is not supported in MacRuby static");
#else
    VALUE result = Qnil;
    VALUE path;
    int type = 0;

    if (search_required(fname, &path, &type)) {
	if (path == 0) {
	    result = Qfalse;
	}
	else {
	    rb_set_safe_level_force(0);
	    rb_provide_feature(path);
	    switch (type) {
		case TYPE_RB:
		    rb_rescue2(load_try, path, load_rescue, path,
			    rb_eException, 0);
		    break;

		case TYPE_RBO:
		    dln_load(RSTRING_PTR(path), false);
		    break;

		case TYPE_BUNDLE:
		    dln_load(RSTRING_PTR(path), true);
		    break;

		default:
		    abort();
	    }
	    result = Qtrue;
	}
    }

    if (NIL_P(result)) {
	load_failed(fname);
    }

    return result;
#endif
}
Beispiel #15
0
VALUE
rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
{
    void* retval;
    void** ffiValues;
    FFIStorage* params;
    VALUE rbReturnValue;
    rbffi_frame_t frame = { 0 };
    
    retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
    
    if (unlikely(fnInfo->blocking)) {
        BlockingCall* bc;

        /*
         * due to the way thread switching works on older ruby variants, we
         * cannot allocate anything passed to the blocking function on the stack
         */
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
        ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
        params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
        bc = ALLOCA_N(BlockingCall, 1);
        bc->retval = retval;
#else
        ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
        params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
        bc = ALLOC_N(BlockingCall, 1);
        bc->retval = xmalloc(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
        bc->stkretval = retval;
#endif
        bc->info = fnInfo;
        bc->function = function;
        bc->ffiValues = ffiValues;
        bc->params = params;
        bc->frame = &frame;

        rbffi_SetupCallParams(argc, argv,
            fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
            fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);

        rbffi_frame_push(&frame); 
        rb_rescue2(do_blocking_call, (VALUE) bc, save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
        rbffi_frame_pop(&frame);

#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
        memcpy(bc->stkretval, bc->retval, MAX(bc->info->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
        xfree(bc->params);
        xfree(bc->ffiValues);
        xfree(bc->retval);
        xfree(bc);
#endif
    
    } else {
static enum MqErrorE
FactoryCreate(
  struct MqS * const tmpl,
  enum MqFactoryE create,
  struct MqFactoryS *item,
  struct MqS  ** mqctxP
)
{
  enum MqErrorE mqret = MQ_OK;
  struct MqS * mqctx = NULL;
  VALUE args;
  VALUE vtmpl;
  VALUE self;

/*
  //struct MqS * const mqctx = tmpl;
  if (create == MQ_FACTORY_NEW_FORK) {
    //rb_thread_atfork();
  }
  if (create == MQ_FACTORY_NEW_THREAD) {
    //RUBY_INIT_STACK;
  }
*/

  // setup templ
  vtmpl = MqS2VAL(tmpl);

  // setup arguments
  args = rb_ary_new3(2, vtmpl, PTR2VAL(item->Create.data));

  // call "new"
  self = rb_rescue2(sFactoryCall, args, sFactoryError, vtmpl, rb_eException, (VALUE)0);

  if (NIL_P(self)) {
    if (create == MQ_FACTORY_NEW_INIT) {
      mqret = MQ_ERROR;
    } else {
      mqret = MqErrorGetCode(tmpl);
    }
  } else {
    mqctx = VAL2MqS(self);
    //rb_gc_register_address((VALUE*)&mqctx->self);
    INCR_REG(self);
    if (create == MQ_FACTORY_NEW_INIT) {
      MqSetupDup(mqctx, tmpl);
    }
  }
  
  *mqctxP = mqctx;
  return mqret;
}
Beispiel #17
0
VALUE kernel_spec_rb_rescue2(int argc, VALUE *args, VALUE self) {
  VALUE main_array, raise_array;

  main_array = rb_ary_new();
  rb_ary_push(main_array, args[0]);
  rb_ary_push(main_array, args[1]);

  raise_array = rb_ary_new();
  rb_ary_push(raise_array, args[2]);
  rb_ary_push(raise_array, args[3]);

  return rb_rescue2(kernel_spec_call_proc, main_array,
      kernel_spec_call_proc, raise_array, args[4], args[5], (VALUE)0);
}
Beispiel #18
0
VALUE shoes_safe_block(VALUE self, VALUE block, VALUE args) {
    safe_block sb;
    VALUE v;

    sb.canvas = shoes_find_canvas(self);
    sb.block = block;
    sb.args = args;
    rb_gc_register_address(&args);

    v = rb_rescue2(CASTHOOK(shoes_safe_block_call), (VALUE)&sb,
                   CASTHOOK(shoes_safe_block_exception), (VALUE)&sb, rb_cObject, 0);
    rb_gc_unregister_address(&args);
    return v;
}
Beispiel #19
0
shoes_code
shoes_start(char *path, char *uri)
{
  shoes_code code = SHOES_OK;
  char bootup[SHOES_BUFSIZE];
  int len = shoes_snprintf(bootup,
    SHOES_BUFSIZE,
    "begin;"
      "DIR = File.expand_path(File.dirname(%%q<%s>));"
      "$:.replace([DIR+'/ruby/lib/'+PLATFORM, DIR+'/ruby/lib', DIR+'/lib']);"
      "require 'shoes';"
      "DIR;"
    "rescue Object => e;"
      "puts(e.message);"
    "end",
    path);

  if (len < 0 || len >= SHOES_BUFSIZE)
  {
    QUIT("Path to script is too long.");
  }

  VALUE str = rb_eval_string(bootup);
  if (NIL_P(str))
    return SHOES_QUIT;

  StringValue(str);
  strcpy(shoes_world->path, RSTRING(str)->ptr);

  char *load_uri_str = NULL;
  VALUE load_uri = rb_rescue2(CASTHOOK(shoes_start_begin), Qnil, CASTHOOK(shoes_start_exception), Qnil, rb_cObject, 0);
  if (!RTEST(load_uri))
    return SHOES_QUIT;
  if (rb_obj_is_kind_of(load_uri, rb_eException))
  {
    QUIT_ALERT(load_uri);
  }

  if (rb_obj_is_kind_of(load_uri, rb_cString))
    load_uri_str = RSTRING_PTR(load_uri);

  code = shoes_load(load_uri_str);
  if (code != SHOES_OK)
    goto quit;

  code = shoes_app_start(shoes_world->apps, uri);
quit:
  return code;
}
Beispiel #20
0
lumi_code
lumi_start(char *path, char *uri)
{
  lumi_code code = LUMI_OK;
  char bootup[LUMI_BUFSIZE];
  int len = lumi_snprintf(bootup,
    LUMI_BUFSIZE,
    "begin;"
      "DIR = File.expand_path(File.dirname(%%q<%s>));"
      "$:.replace([DIR+'/ruby/lib/'+(ENV['LUMI_RUBY_ARCH'] || RUBY_PLATFORM), DIR+'/ruby/lib', DIR+'/lib', '.']);"
      "require 'lumi';"
      "DIR;"
    "rescue Object => e;"
      "puts(e.message);"
    "end",
    path);

  if (len < 0 || len >= LUMI_BUFSIZE)
  {
    QUIT("Path to script is too long.");
  }

  VALUE str = rb_eval_string(bootup);
  if (NIL_P(str))
    return LUMI_QUIT;

  StringValue(str);
  strcpy(lumi_world->path, RSTRING_PTR(str));

  char *load_uri_str = NULL;
  VALUE load_uri = rb_rescue2(CASTHOOK(lumi_start_begin), Qnil, CASTHOOK(lumi_start_exception), Qnil, rb_cObject, 0);
  if (!RTEST(load_uri))
    return LUMI_QUIT;
  if (rb_obj_is_kind_of(load_uri, rb_eException))
  {
    QUIT_ALERT(load_uri);
  }

  if (rb_obj_is_kind_of(load_uri, rb_cString))
    load_uri_str = RSTRING_PTR(load_uri);

  code = lumi_load(load_uri_str);
  if (code != LUMI_OK)
    goto quit;

  code = lumi_app_start(lumi_world->apps, uri);
quit:
  return code;
}
 inline void rescue(RetT* out, Arg1T* arg1, Arg2T* arg2, Arg3T* arg3, Arg4T* arg4)
 {
     auto f1 = rescue_begin_body<RetT, Arg1T, Arg2T, Arg3T, Arg4T, Func>;
     auto f2 = rescue_rescue_block;
     void* data[5];
     data[0] = reinterpret_cast<void*>(out);
     data[1] = reinterpret_cast<void*>(arg1);
     data[2] = reinterpret_cast<void*>(arg2);
     data[3] = reinterpret_cast<void*>(arg3);
     data[4] = reinterpret_cast<void*>(arg4);
     VALUE ex = Qnil;
     rb_rescue2((VALUE(*)(...))f1, (VALUE)data, (VALUE(*)(...))f2, (VALUE)&ex, rb_eException, 0);
     if (ex != Qnil)
         throw Exception(ex);
 }
Beispiel #22
0
VALUE
rbffi_thread_blocking_region(VALUE (*func)(void *), void *data1, void (*ubf)(void *), void *data2)
{
    struct BlockingThread* thr;
    int fd[2];
    VALUE exc;
    DWORD state;
    DWORD res;

    if (_pipe(fd, 1024, O_BINARY) == -1) {
        rb_raise(rb_eSystemCallError, "_pipe() failed");
        return Qnil;
    }

    thr = ALLOC_N(struct BlockingThread, 1);
    thr->rdfd = fd[0];
    thr->wrfd = fd[1];
    thr->fn = func;
    thr->data = data1;
    thr->ubf = ubf;
    thr->data2 = data2;
    thr->retval = Qnil;

    thr->tid = CreateThread(NULL, 0, rbffi_blocking_thread, thr, 0, NULL);
    if (!thr->tid) {
        close(fd[0]);
        close(fd[1]);
        xfree(thr);
        rb_raise(rb_eSystemCallError, "CreateThread() failed");
        return Qnil;
    }

    exc = rb_rescue2(wait_for_thread, (VALUE) thr, cleanup_blocking_thread, (VALUE) thr,
        rb_eException);

    /* The thread should be finished, already. */
    WaitForSingleObject(thr->tid, INFINITE);
    CloseHandle(thr->tid);
    close(fd[1]);
    close(fd[0]);
    xfree(thr);

    if (exc != Qnil) {
        rb_exc_raise(exc);
    }

    return thr->retval;
}
Beispiel #23
0
static VALUE
lazy_zip_func(VALUE val, VALUE arg, int argc, VALUE *argv)
{
    VALUE yielder, ary, v;
    long i;

    yielder = argv[0];
    ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
    rb_ary_push(ary, argv[1]);
    for (i = 0; i < RARRAY_LEN(arg); i++) {
	v = rb_rescue2(call_next, RARRAY_PTR(arg)[i], next_stopped, 0,
		       rb_eStopIteration, (VALUE)0);
	rb_ary_push(ary, v);
    }
    rb_funcall(yielder, id_yield, 1, ary);
    return Qnil;
}
Beispiel #24
0
static VALUE Unpacker_each(VALUE self)
{
    UNPACKER(self, uk);

#ifdef RETURN_ENUMERATOR
    RETURN_ENUMERATOR(self, 0, 0);
#endif

    if(msgpack_buffer_has_io(UNPACKER_BUFFER_(uk))) {
        return Unpacker_each_impl(self);
    } else {
        /* rescue EOFError only if io is set */
        return rb_rescue2(Unpacker_each_impl, self,
                Unpacker_rescue_EOFError, self,
                rb_eEOFError, NULL);
    }
}
Beispiel #25
0
Datei: ruby.c Projekt: filp/slash
static void
sl_ruby_protect(sl_vm_t* vm, void(*func)(sl_vm_t*,void*), void* data)
{
    struct sl_ruby_protect_args args = { vm, data, func, 0, { 0 } };
    sl_vm_frame_t frame;
    pthread_mutex_lock(&sl_ruby_lock);
    SL_ENSURE(frame, {
        rb_rescue2(sl_ruby_protect_try, (VALUE)&args, sl_ruby_protect_catch, (VALUE)&args, rb_eException, 0);
        pthread_mutex_unlock(&sl_ruby_lock);
        if(args.exception) {
            SLVAL Ruby_Exception = sl_vm_store_get(vm, &cRuby_Exception);
            SLVAL err = sl_allocate(vm, Ruby_Exception);
            sl_error_set_message(vm, err, sl_ruby_to_slash(vm, rb_obj_as_string(args.exception)));
            sl_set_ivar(vm, err, sl_intern(vm, "object"), make_ruby_object(vm, args.exception));
            args.sl_exception = err;
        }
    }, {
Beispiel #26
0
VALUE
rbffi_thread_blocking_region(VALUE (*func)(void *), void *data1, void (*ubf)(void *), void *data2)
{
    struct BlockingThread* thr;
    int fd[2];
    VALUE exc;
    
    if (pipe(fd) < 0) {
        rb_raise(rb_eSystemCallError, "pipe(2) failed");
        return Qnil;
    }
    fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) | O_NONBLOCK);

    thr = ALLOC_N(struct BlockingThread, 1);
    thr->rdfd = fd[0];
    thr->wrfd = fd[1];
    thr->fn = func;
    thr->data = data1;
    thr->ubf = ubf;
    thr->data2 = data2;
    thr->retval = Qnil;

    if (pthread_create(&thr->tid, NULL, rbffi_blocking_thread, thr) != 0) {
        close(fd[0]);
        close(fd[1]);
        xfree(thr);
        rb_raise(rb_eSystemCallError, "pipe(2) failed");
        return Qnil;
    }

    exc = rb_rescue2(wait_for_thread, (VALUE) thr, cleanup_blocking_thread, (VALUE) thr,
        rb_eException);
    
    pthread_join(thr->tid, NULL);
    close(fd[1]);
    close(fd[0]);
    xfree(thr);

    if (exc != Qnil) {
        rb_exc_raise(exc);
    }

    return thr->retval;
}
Beispiel #27
0
shoes_code
shoes_load(char *path)
{
  shoes_code code = SHOES_QUIT;
  char bootup[SHOES_BUFSIZE];

  if (path)
  {
    sprintf(bootup, "Shoes.load(%%q<%s>);", path);

    VALUE v = rb_rescue2(CASTHOOK(shoes_load_begin), (VALUE)bootup, CASTHOOK(shoes_load_exception), Qnil, rb_cObject, 0);
    if (rb_obj_is_kind_of(v, rb_eException))
    {
      QUIT_ALERT(v);
    }
  }

  return SHOES_OK;
}
Beispiel #28
0
static VALUE
lazy_flat_map_func(VALUE val, VALUE m, int argc, VALUE *argv)
{
    VALUE result = rb_yield_values2(argc - 1, &argv[1]);
    if (TYPE(result) == T_ARRAY) {
	long i;
	for (i = 0; i < RARRAY_LEN(result); i++) {
	    rb_funcall(argv[0], id_yield, 1, RARRAY_PTR(result)[i]);
	}
    }
    else {
	NODE *memo;
	memo = NEW_MEMO(result, argv[0], 0);
	rb_rescue2(lazy_flat_map_each, (VALUE) memo,
		   lazy_flat_map_to_ary, (VALUE) memo,
		   rb_eNoMethodError, (VALUE)0);
    }
    return Qnil;
}
Beispiel #29
0
lumi_code
lumi_load(char *path)
{
  char bootup[LUMI_BUFSIZE];

  if (path)
  {
    sprintf(bootup, "Lumi.visit(%%q<%s>);", path);

    VALUE v = rb_rescue2(CASTHOOK(lumi_load_begin), (VALUE)bootup, CASTHOOK(lumi_load_exception), Qnil, rb_cObject, 0);
    if (rb_obj_is_kind_of(v, rb_eException))
    {
      lumi_canvas_error(Qnil, v);
      rb_eval_string("Lumi.show_log");
    }
  }

  return LUMI_OK;
}
static inline size_t read_until_eof(msgpack_buffer_t* b, VALUE out, unsigned long max)
{
    if(msgpack_buffer_has_io(b)) {
        size_t sz = 0;
        VALUE args[4] = { (VALUE)(void*) b, out, (VALUE) max, (VALUE)(void*) &sz };
        rb_rescue2(read_until_eof_rescue, (VALUE)(void*) args,
                read_until_eof_error, (VALUE)(void*) args,
                rb_eEOFError, NULL);
        return sz;

    } else {
        if(max == 0) {
            max = ULONG_MAX;
        }
        if(out == Qnil) {
            return msgpack_buffer_skip_nonblock(b, max);
        } else {
            return msgpack_buffer_read_to_string_nonblock(b, out, max);
        }
    }
}