Пример #1
0
 private IRubyObject doCallProcForObj(IRubyObject result) {
   if (proc != null) {
     // return the result of the proc, but not for symbols
     return Helpers.invoke(getRuntime().getCurrentContext(), proc, "call", result);
   }
   return result;
 }
Пример #2
0
  @JRubyMethod(module = true)
  public static IRubyObject timeout(
      final ThreadContext context,
      IRubyObject timeout,
      IRubyObject seconds,
      IRubyObject exceptionType,
      Block block) {
    // No seconds, just yield
    if (seconds.isNil() || Helpers.invoke(context, seconds, "zero?").isTrue()) {
      return block.yieldSpecific(context);
    }

    final Ruby runtime = context.runtime;

    // No timeout in critical section
    if (runtime.getThreadService().getCritical()) {
      return raiseBecauseCritical(context);
    }

    final RubyThread currentThread = context.getThread();
    final AtomicBoolean latch = new AtomicBoolean(false);

    IRubyObject id = new RubyObject(runtime, runtime.getObject());
    RubyClass anonException = (RubyClass) runtime.getClassFromPath("Timeout::AnonymousException");
    Runnable timeoutRunnable =
        exceptionType.isNil()
            ? prepareRunnable(currentThread, runtime, latch, id)
            : prepareRunnableWithException(currentThread, exceptionType, runtime, latch);
    Future timeoutFuture = null;

    try {
      try {
        timeoutFuture =
            timeoutExecutor.schedule(
                timeoutRunnable,
                (long) (seconds.convertToFloat().getDoubleValue() * 1000000),
                TimeUnit.MICROSECONDS);

        return block.yield(context, seconds);
      } finally {
        killTimeoutThread(context, timeoutFuture, latch);
      }
    } catch (RaiseException re) {
      // if it's the exception we're expecting
      if (re.getException().getMetaClass() == anonException) {
        // and we were not given a specific exception
        if (exceptionType.isNil()) {
          // and it's the exception intended for us
          if (re.getException().getInternalVariable("__identifier__") == id) {
            return raiseTimeoutError(context, re);
          }
        }
      }

      // otherwise, rethrow
      throw re;
    }
  }
Пример #3
0
 private static RangeLike rangeValues(ThreadContext context, IRubyObject range) {
   RangeLike like = new RangeLike();
   if (range instanceof RubyRange) {
     RubyRange vrange = (RubyRange) range;
     like.begin = vrange.first(context);
     like.end = vrange.last(context);
     like.excl = vrange.exclude_end_p().isTrue();
   } else {
     if (!range.respondsTo("begin")
         || !range.respondsTo("end")
         || !range.respondsTo("exclude_end?")) {
       return null;
     }
     like.begin = Helpers.invoke(context, range, "begin");
     like.end = Helpers.invoke(context, range, "end");
     like.excl = Helpers.invoke(context, range, "exlucde_end?").isTrue();
   }
   like.range = Helpers.invoke(context, like.end, "-", like.begin);
   return like;
 }
Пример #4
0
    protected IRubyObject case_aware_op_aset(
        ThreadContext context, IRubyObject key, final IRubyObject value, boolean caseSensitive) {
      if (!key.respondsTo("to_str")) {
        throw getRuntime().newTypeError("can't convert " + key.getMetaClass() + " into String");
      }
      if (!value.respondsTo("to_str") && !value.isNil()) {
        throw getRuntime().newTypeError("can't convert " + value.getMetaClass() + " into String");
      }

      if (!caseSensitive) {
        key = getCorrectKey(key, context);
      }

      if (value.isNil()) {
        return super.delete(context, key, org.jruby.runtime.Block.NULL_BLOCK);
      }

      IRubyObject keyAsStr = normalizeEnvString(Helpers.invoke(context, key, "to_str"));
      IRubyObject valueAsStr =
          value.isNil()
              ? context.nil
              : normalizeEnvString(Helpers.invoke(context, value, "to_str"));

      if (updateRealENV) {
        POSIX posix = context.runtime.getPosix();
        String keyAsJava = keyAsStr.asJavaString();
        // libc (un)setenv is not reentrant, so we need to synchronize across the entire JVM
        // (JRUBY-5933)
        if (valueAsStr == context.nil) {
          synchronized (Object.class) {
            posix.unsetenv(keyAsJava);
          }
        } else {
          synchronized (Object.class) {
            posix.setenv(keyAsJava, valueAsStr.asJavaString(), 1);
          }
        }
      }

      return super.op_aset(context, keyAsStr, valueAsStr);
    }
Пример #5
0
  @JRubyMethod(name = "ruby", meta = true)
  public static IRubyObject ruby(ThreadContext context, IRubyObject recv) {
    Ruby runtime = context.runtime;
    RubyHash configHash = (RubyHash) runtime.getModule("RbConfig").getConstant("CONFIG");

    IRubyObject bindir = configHash.op_aref(context, runtime.newString("bindir"));
    IRubyObject ruby_install_name =
        configHash.op_aref(context, runtime.newString("ruby_install_name"));
    IRubyObject exeext = configHash.op_aref(context, runtime.newString("EXEEXT"));

    return Helpers.invoke(
        context,
        runtime.getClass("File"),
        "join",
        bindir,
        ruby_install_name.callMethod(context, "+", exeext));
  }
Пример #6
0
 public IRubyObject dispatch(
     String method_name,
     IRubyObject arg1,
     IRubyObject arg2,
     IRubyObject arg3,
     IRubyObject arg4,
     IRubyObject arg5) {
   return Helpers.invoke(
       context,
       ripper,
       method_name,
       escape(arg1),
       escape(arg2),
       escape(arg3),
       escape(arg4),
       escape(arg5));
 }
Пример #7
0
 // c: rb_random_real
 public static double randomReal(ThreadContext context, IRubyObject obj) {
   RandomType random = null;
   if (obj.equals(context.runtime.getRandomClass())) {
     random = getDefaultRand(context);
   }
   if (obj instanceof RubyRandom) {
     random = ((RubyRandom) obj).random;
   }
   if (random != null) {
     return random.genrandReal();
   }
   double d = RubyNumeric.num2dbl(Helpers.invoke(context, obj, "rand"));
   if (d < 0.0 || d >= 1.0) {
     throw context.runtime.newRangeError("random number too big: " + d);
   }
   return d;
 }
Пример #8
0
  @JRubyMethod(module = true)
  public static IRubyObject timeout(
      final ThreadContext context, IRubyObject timeout, IRubyObject seconds, Block block) {
    // No seconds, just yield
    if (seconds.isNil() || Helpers.invoke(context, seconds, "zero?").isTrue()) {
      return block.yieldSpecific(context);
    }

    final Ruby runtime = context.runtime;

    // No timeout in critical section
    if (runtime.getThreadService().getCritical()) {
      return raiseBecauseCritical(context);
    }

    final RubyThread currentThread = context.getThread();
    final AtomicBoolean latch = new AtomicBoolean(false);

    IRubyObject id = new RubyObject(runtime, runtime.getObject());
    Runnable timeoutRunnable = prepareRunnable(currentThread, runtime, latch, id);
    Future timeoutFuture = null;

    try {
      try {
        timeoutFuture =
            timeoutExecutor.schedule(
                timeoutRunnable,
                (long) (seconds.convertToFloat().getDoubleValue() * 1000000),
                TimeUnit.MICROSECONDS);

        return block.yield(context, seconds);
      } finally {
        killTimeoutThread(context, timeoutFuture, latch);
      }
    } catch (RaiseException re) {
      if (re.getException().getInternalVariable("__identifier__") == id) {
        return raiseTimeoutError(context, re);
      } else {
        throw re;
      }
    }
  }
Пример #9
0
  private static JavaClass getTargetType(ThreadContext context, Ruby runtime, IRubyObject type) {
    JavaClass targetType;

    if (type instanceof RubyString || type instanceof RubySymbol) {
      targetType = runtime.getJavaSupport().getNameClassMap().get(type.asJavaString());
      if (targetType == null) targetType = JavaClass.forNameVerbose(runtime, type.asJavaString());
    } else if (type instanceof RubyModule && type.respondsTo("java_class")) {
      targetType = (JavaClass) Helpers.invoke(context, type, "java_class");
    } else if (type instanceof JavaProxy) {
      if (((JavaProxy) type).getObject() instanceof Class) {
        targetType = JavaClass.get(runtime, (Class) ((JavaProxy) type).getObject());
      } else {
        throw runtime.newTypeError("not a valid target type: " + type);
      }
    } else {
      throw runtime.newTypeError("unable to convert to type: " + type);
    }

    return targetType;
  }
Пример #10
0
 public IRubyObject dispatch(String method_name, IRubyObject arg1) {
   return Helpers.invoke(context, ripper, method_name, escape(arg1));
 }
Пример #11
0
 public IRubyObject dispatch(String method_name) {
   return Helpers.invoke(context, ripper, method_name);
 }
Пример #12
0
 /** num_to_int */
 @JRubyMethod(name = "to_int")
 public IRubyObject to_int(ThreadContext context) {
   return Helpers.invoke(context, this, "to_i");
 }
Пример #13
0
 /** num_fdiv (1.9) */
 @JRubyMethod(name = "fdiv")
 public IRubyObject fdiv(ThreadContext context, IRubyObject other) {
   return Helpers.invoke(context, this.convertToFloat(), "/", other);
 }
Пример #14
0
 // c: random_rand
 private static IRubyObject randomRand(
     ThreadContext context, IRubyObject vmax, RandomType random) {
   IRubyObject v;
   RangeLike range = null;
   if (vmax.isNil()) {
     v = context.nil;
   } else if ((v = checkMaxInt(context, vmax)) != null) {
     v = randInt(context, random, (RubyInteger) v, true);
   } else if (!(v = TypeConverter.checkFloatType(context.runtime, vmax)).isNil()) {
     double max = floatValue(v);
     if (max > 0.0) {
       v = context.runtime.newFloat(max * random.genrandReal());
     } else {
       v = context.nil;
     }
   } else if ((range = rangeValues(context, vmax)) != null) {
     if ((v = checkMaxInt(context, range.range)) != null) {
       if (v instanceof RubyFixnum) {
         long max = ((RubyFixnum) v).getLongValue();
         if (range.excl) {
           max -= 1;
         }
         if (max >= 0) {
           v = randLimitedFixnum(context, random, max);
         } else {
           v = context.nil;
         }
       } else if (v instanceof RubyBignum) {
         BigInteger big = ((RubyBignum) v).getBigIntegerValue();
         if (!big.equals(BigInteger.ZERO) && (big.signum() > 0)) {
           if (range.excl) {
             big = big.subtract(BigInteger.ONE);
           }
           v = randLimitedBignum(context, random, RubyBignum.newBignum(context.runtime, big));
         } else {
           v = context.nil;
         }
       } else {
         v = context.nil;
       }
     } else if (!(v = TypeConverter.checkFloatType(context.runtime, range.range)).isNil()) {
       int scale = 1;
       double max = ((RubyFloat) v).getDoubleValue();
       double mid = 0.5;
       double r;
       if (Double.isInfinite(max)) {
         double min = floatValue(range.begin) / 2.0;
         max = floatValue(range.end) / 2.0;
         scale = 2;
         mid = max + min;
         max -= min;
       } else {
         floatValue(v);
       }
       v = context.nil;
       if (max > 0.0) {
         if (range.excl) {
           r = random.genrandReal();
         } else {
           r = random.genrandReal2();
         }
         if (scale > 1) {
           return context.runtime.newFloat(+(+(+(r - 0.5) * max) * scale) + mid);
         }
         v = context.runtime.newFloat(r * max);
       } else if (max == 0.0 && !range.excl) {
         v = context.runtime.newFloat(0.0);
       }
     }
   } else {
     v = context.nil;
     RubyNumeric.num2long(vmax); // need check here to raise TypeError
   }
   if (v.isNil()) {
     throw context.runtime.newArgumentError("invalid argument - " + vmax.toString());
   }
   if (range == null) {
     return v;
   }
   if ((range.begin instanceof RubyFixnum) && (v instanceof RubyFixnum)) {
     long x = ((RubyFixnum) range.begin).getLongValue() + ((RubyFixnum) v).getLongValue();
     return context.runtime.newFixnum(x);
   }
   if (v instanceof RubyBignum) {
     return ((RubyBignum) v).op_plus(context, range.begin);
   } else if (v instanceof RubyFloat) {
     IRubyObject f = TypeConverter.checkFloatType(context.runtime, range.begin);
     if (!f.isNil()) {
       return ((RubyFloat) v).op_plus(context, f);
     }
   }
   return Helpers.invoke(context, range.begin, "+", v);
 }