Beispiel #1
0
  @SuppressWarnings("unchecked")
  @JRubyMethod(name = "names")
  public IRubyObject names(ThreadContext context) {
    Ruby runtime = context.runtime;
    EncodingService service = runtime.getEncodingService();
    Entry entry = service.findEncodingOrAliasEntry(name);

    RubyArray result = runtime.newArray();
    HashEntryIterator i;
    i = service.getEncodings().entryIterator();
    while (i.hasNext()) {
      CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry> e =
          ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>) i.next());
      if (e.value == entry) {
        result.append(
            RubyString.newUsAsciiStringShared(runtime, e.bytes, e.p, e.end - e.p).freeze(context));
      }
    }
    i = service.getAliases().entryIterator();
    while (i.hasNext()) {
      CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry> e =
          ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>) i.next());
      if (e.value == entry) {
        result.append(
            RubyString.newUsAsciiStringShared(runtime, e.bytes, e.p, e.end - e.p).freeze(context));
      }
    }
    result.append(runtime.newString(EXTERNAL));
    result.append(runtime.newString(LOCALE));

    return result;
  }
Beispiel #2
0
 /** match_end */
 @JRubyMethod(name = "end", compat = CompatVersion.RUBY1_8)
 public IRubyObject end(ThreadContext context, IRubyObject index) {
   int i = RubyNumeric.num2int(index);
   Ruby runtime = context.getRuntime();
   int e = endCommon(runtime, i);
   return e < 0 ? runtime.getNil() : RubyFixnum.newFixnum(runtime, e);
 }
Beispiel #3
0
  public static RubyClass createThreadClass(Ruby runtime) {
    // FIXME: In order for Thread to play well with the standard 'new' behavior,
    // it must provide an allocator that can create empty object instances which
    // initialize then fills with appropriate data.
    RubyClass threadClass =
        runtime.defineClass(
            "Thread", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
    runtime.setThread(threadClass);

    threadClass.index = ClassIndex.THREAD;
    threadClass.setReifiedClass(RubyThread.class);

    threadClass.defineAnnotatedMethods(RubyThread.class);

    RubyThread rubyThread = new RubyThread(runtime, threadClass);
    // TODO: need to isolate the "current" thread from class creation
    rubyThread.threadImpl = new NativeThread(rubyThread, Thread.currentThread());
    runtime.getThreadService().setMainThread(Thread.currentThread(), rubyThread);

    // set to default thread group
    runtime.getDefaultThreadGroup().addDirectly(rubyThread);

    threadClass.setMarshal(ObjectMarshal.NOT_MARSHALABLE_MARSHAL);

    return threadClass;
  }
Beispiel #4
0
  public static IRubyObject lexicalSearchConst(
      ThreadContext context,
      StaticScope scope,
      MutableCallSite site,
      String constName,
      boolean noPrivateConsts)
      throws Throwable {
    Ruby runtime = context.runtime;

    IRubyObject constant = scope.getConstantInner(constName);

    if (constant == null) {
      constant = UndefinedValue.UNDEFINED;
    }

    SwitchPoint switchPoint = (SwitchPoint) runtime.getConstantInvalidator(constName).getData();

    // bind constant until invalidated
    MethodHandle target = Binder.from(site.type()).drop(0, 2).constant(constant);
    MethodHandle fallback =
        Binder.from(site.type())
            .append(site, constName)
            .append(noPrivateConsts)
            .invokeStatic(LOOKUP, Bootstrap.class, "lexicalSearchConst");

    site.setTarget(switchPoint.guardWithTest(target, fallback));

    return constant;
  }
Beispiel #5
0
  private IRubyObject handleReturnJump(
      ThreadContext context, JumpException.ReturnJump rj, int jumpTarget) {
    int target = rj.getTarget();
    Ruby runtime = context.getRuntime();

    // lambda always just returns the value
    if (target == jumpTarget && isLambda()) {
      return (IRubyObject) rj.getValue();
    }

    // returns can't propagate out of threads
    if (isThread()) {
      throw runtime.newThreadError("return can't jump across threads");
    }

    // If the block-receiving method is not still active and the original
    // enclosing frame is no longer on the stack, it's a bad return.
    // FIXME: this is not very efficient for cases where it won't error
    if (target == jumpTarget && !context.isJumpTargetAlive(target, 1)) {
      throw runtime.newLocalJumpError(
          RubyLocalJumpError.Reason.RETURN, (IRubyObject) rj.getValue(), "unexpected return");
    }

    // otherwise, let it propagate
    throw rj;
  }
Beispiel #6
0
  @SuppressWarnings("unchecked")
  @JRubyMethod(name = "name_list", meta = true)
  public static IRubyObject name_list(ThreadContext context, IRubyObject recv) {
    Ruby runtime = context.runtime;
    EncodingService service = runtime.getEncodingService();

    RubyArray result =
        runtime.newArray(service.getEncodings().size() + service.getAliases().size());
    HashEntryIterator i;
    i = service.getEncodings().entryIterator();
    while (i.hasNext()) {
      CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry> e =
          ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>) i.next());
      result.append(
          RubyString.newUsAsciiStringShared(runtime, e.bytes, e.p, e.end - e.p).freeze(context));
    }
    i = service.getAliases().entryIterator();
    while (i.hasNext()) {
      CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry> e =
          ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>) i.next());
      result.append(
          RubyString.newUsAsciiStringShared(runtime, e.bytes, e.p, e.end - e.p).freeze(context));
    }

    result.append(runtime.newString(EXTERNAL));
    result.append(runtime.newString(LOCALE));

    return result;
  }
Beispiel #7
0
 @JRubyMethod(name = "_id2ref", required = 1, module = true, visibility = Visibility.PRIVATE)
 public static IRubyObject id2ref(IRubyObject recv, IRubyObject id) {
   Ruby runtime = id.getRuntime();
   if (!(id instanceof RubyFixnum)) {
     throw recv.getRuntime().newTypeError(id, recv.getRuntime().getFixnum());
   }
   RubyFixnum idFixnum = (RubyFixnum) id;
   long longId = idFixnum.getLongValue();
   if (longId == 0) {
     return runtime.getFalse();
   } else if (longId == 2) {
     return runtime.getTrue();
   } else if (longId == 4) {
     return runtime.getNil();
   } else if (longId % 2 != 0) {
     // odd
     return runtime.newFixnum((longId - 1) / 2);
   } else {
     if (runtime.isObjectSpaceEnabled()) {
       IRubyObject object = runtime.getObjectSpace().id2ref(longId);
       if (object == null) {
         return runtime.getNil();
       }
       return object;
     } else {
       runtime
           .getWarnings()
           .warn("ObjectSpace is disabled; _id2ref only supports immediates, pass -X+O to enable");
       return runtime.getNil();
     }
   }
 }
Beispiel #8
0
  /** flo_to_s */
  @JRubyMethod(name = "to_s")
  @Override
  public IRubyObject to_s() {
    Ruby runtime = getRuntime();
    if (Double.isInfinite(value))
      return RubyString.newString(runtime, value < 0 ? "-Infinity" : "Infinity");
    if (Double.isNaN(value)) return RubyString.newString(runtime, "NaN");

    ByteList buf = new ByteList();
    // Under 1.9, use full-precision float formatting (JRUBY-4846).
    // Double-precision can represent around 16 decimal digits;
    // we use 20 to ensure full representation.
    Sprintf.sprintf(buf, Locale.US, "%#.20g", this);
    int e = buf.indexOf('e');
    if (e == -1) e = buf.getRealSize();
    ASCIIEncoding ascii = ASCIIEncoding.INSTANCE;

    if (!ascii.isDigit(buf.get(e - 1))) {
      buf.setRealSize(0);
      Sprintf.sprintf(buf, Locale.US, "%#.14e", this);
      e = buf.indexOf('e');
      if (e == -1) e = buf.getRealSize();
    }

    int p = e;
    while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
    System.arraycopy(buf.getUnsafeBytes(), e, buf.getUnsafeBytes(), p, buf.getRealSize() - e);
    buf.setRealSize(p + buf.getRealSize() - e);

    buf.setEncoding(USASCIIEncoding.INSTANCE);

    return runtime.newString(buf);
  }
Beispiel #9
0
  public static RubyClass createFloatClass(Ruby runtime) {
    RubyClass floatc =
        runtime.defineClass(
            "Float", runtime.getNumeric(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
    runtime.setFloat(floatc);

    floatc.setClassIndex(ClassIndex.FLOAT);
    floatc.setReifiedClass(RubyFloat.class);

    floatc.kindOf = new RubyModule.JavaClassKindOf(RubyFloat.class);

    floatc.getSingletonClass().undefineMethod("new");

    // Java Doubles are 64 bit long:
    floatc.defineConstant("ROUNDS", RubyFixnum.newFixnum(runtime, ROUNDS));
    floatc.defineConstant("RADIX", RubyFixnum.newFixnum(runtime, RADIX));
    floatc.defineConstant("MANT_DIG", RubyFixnum.newFixnum(runtime, MANT_DIG));
    floatc.defineConstant("DIG", RubyFixnum.newFixnum(runtime, DIG));
    // Double.MAX_EXPONENT since Java 1.6
    floatc.defineConstant("MIN_EXP", RubyFixnum.newFixnum(runtime, MIN_EXP));
    // Double.MAX_EXPONENT since Java 1.6
    floatc.defineConstant("MAX_EXP", RubyFixnum.newFixnum(runtime, MAX_EXP));
    floatc.defineConstant("MIN_10_EXP", RubyFixnum.newFixnum(runtime, MIN_10_EXP));
    floatc.defineConstant("MAX_10_EXP", RubyFixnum.newFixnum(runtime, MAX_10_EXP));
    floatc.defineConstant("MIN", RubyFloat.newFloat(runtime, Double.MIN_VALUE));
    floatc.defineConstant("MAX", RubyFloat.newFloat(runtime, Double.MAX_VALUE));
    floatc.defineConstant("EPSILON", RubyFloat.newFloat(runtime, EPSILON));

    floatc.defineConstant("INFINITY", RubyFloat.newFloat(runtime, INFINITY));
    floatc.defineConstant("NAN", RubyFloat.newFloat(runtime, NAN));

    floatc.defineAnnotatedMethods(RubyFloat.class);

    return floatc;
  }
Beispiel #10
0
 @Override
 public RubyHash to_hash() {
   Ruby runtime = getRuntime();
   RubyHash hash = RubyHash.newHash(runtime);
   hash.replace(runtime.getCurrentContext(), this);
   return hash;
 }
Beispiel #11
0
  /** do_coerce */
  protected final RubyArray doCoerce(ThreadContext context, IRubyObject other, boolean err) {
    if (!other.respondsTo("coerce")) {
      if (err) {
        coerceRescue(context, other);
      }
      return null;
    }
    final Ruby runtime = context.runtime;
    final IRubyObject $ex = context.getErrorInfo();
    final IRubyObject result;
    try {
      result = coerceBody(context, other);
    } catch (RaiseException e) { // e.g. NoMethodError: undefined method `coerce'
      if (e.getException().kind_of_p(context, runtime.getStandardError()).isTrue()) {
        context.setErrorInfo($ex); // restore $!
        RubyWarnings warnings = context.runtime.getWarnings();
        warnings.warn("Numerical comparison operators will no more rescue exceptions of #coerce");
        warnings.warn("in the next release. Return nil in #coerce if the coercion is impossible.");
        if (err) {
          coerceFailed(context, other);
        }
        return null;
      } else {
        throw e;
      }
    }

    return coerceResult(runtime, result, err);
  }
Beispiel #12
0
 private IRubyObject stepCommon19(ThreadContext context, IRubyObject step, Block block) {
   Ruby runtime = context.getRuntime();
   if (begin instanceof RubyFixnum && end instanceof RubyFixnum && step instanceof RubyFixnum) {
     fixnumStep(context, runtime, ((RubyFixnum) step).getLongValue(), block);
   } else if (begin instanceof RubyFloat
       || end instanceof RubyFloat
       || step instanceof RubyFloat) {
     RubyNumeric.floatStep19(context, runtime, begin, end, step, isExclusive, block);
   } else if (begin instanceof RubyNumeric
       || !checkIntegerType(runtime, begin, "to_int").isNil()
       || !checkIntegerType(runtime, end, "to_int").isNil()) {
     numericStep19(context, runtime, step, block);
   } else {
     IRubyObject tmp = begin.checkStringType();
     if (!tmp.isNil()) {
       StepBlockCallBack callback = new StepBlockCallBack(block, RubyFixnum.one(runtime), step);
       Block blockCallback =
           CallBlock.newCallClosure(
               this, runtime.getRange(), Arity.singleArgument(), callback, context);
       ((RubyString) tmp).uptoCommon19(context, end, isExclusive, blockCallback);
     } else {
       if (!begin.respondsTo("succ"))
         throw runtime.newTypeError("can't iterate from " + begin.getMetaClass().getName());
       // range_each_func(range, step_i, b, e, args);
       rangeEach(context, new StepBlockCallBack(block, RubyFixnum.one(runtime), step));
     }
   }
   return this;
 }
Beispiel #13
0
  private static IRubyObject callCmpMethod(
      ThreadContext context, IRubyObject recv, IRubyObject other, IRubyObject returnValueOnError) {
    Ruby runtime = context.runtime;

    if (recv == other) return runtime.getTrue();

    try {
      IRubyObject result = invokedynamic(context, recv, OP_CMP, other);

      // This is only to prevent throwing exceptions by cmperr - it has poor performance
      if (result.isNil()) {
        return returnValueOnError;
      }

      return RubyBoolean.newBoolean(runtime, cmpint(context, result, recv, other) == 0);
    } catch (RaiseException e) {
      if (e.getException().kind_of_p(context, runtime.getStandardError()).isTrue()) {
        // clear error info resulting from failure to compare (JRUBY-3292)
        context.setErrorInfo(runtime.getNil());
        return returnValueOnError;
      } else {
        throw e;
      }
    }
  }
Beispiel #14
0
  @JRubyMethod(name = "round", compat = CompatVersion.RUBY1_9)
  public IRubyObject round19(ThreadContext context, IRubyObject arg) {
    int ndigits = RubyNumeric.num2int(arg);
    if (ndigits > 0) return RubyKernel.new_float(this, this);
    if (ndigits == 0) return this;
    ndigits = -ndigits;
    Ruby runtime = context.getRuntime();
    if (ndigits < 0) throw runtime.newArgumentError("ndigits out of range");
    IRubyObject f = Numeric.int_pow(context, 10, ndigits);

    if (this instanceof RubyFixnum && f instanceof RubyFixnum) {
      long x = ((RubyFixnum) this).getLongValue();
      long y = ((RubyFixnum) f).getLongValue();
      boolean neg = x < 0;
      if (neg) x = -x;
      x = (x + y / 2) / y * y;
      if (neg) x = -x;
      return RubyFixnum.newFixnum(runtime, x);
    } else {
      IRubyObject h = f.callMethod(context, "/", RubyFixnum.two(runtime));
      IRubyObject r = callMethod(context, "%", f);
      IRubyObject n = callMethod(context, "-", r);
      if (!r.callMethod(context, "<", h).isTrue()) n = n.callMethod(context, "+", f);
      return n;
    }
  }
Beispiel #15
0
  public static RubyClass createIntegerClass(Ruby runtime) {
    RubyClass integer =
        runtime.defineClass(
            "Integer", runtime.getNumeric(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
    runtime.setInteger(integer);

    integer.index = ClassIndex.INTEGER;
    integer.setReifiedClass(RubyInteger.class);

    integer.kindOf =
        new RubyModule.KindOf() {
          public boolean isKindOf(IRubyObject obj, RubyModule type) {
            return obj instanceof RubyInteger;
          }
        };

    integer.getSingletonClass().undefineMethod("new");

    if (!runtime.is1_9()) {
      integer.includeModule(runtime.getPrecision());
    }

    integer.defineAnnotatedMethods(RubyInteger.class);

    return integer;
  }
Beispiel #16
0
  public static RubyClass createPointerClass(Ruby runtime, RubyModule module) {
    RubyClass pointerClass =
        module.defineClassUnder(
            "Pointer",
            module.getClass(AbstractMemory.ABSTRACT_MEMORY_RUBY_CLASS),
            RubyInstanceConfig.REIFY_RUBY_CLASSES
                ? new ReifyingAllocator(Pointer.class)
                : PointerAllocator.INSTANCE);

    pointerClass.defineAnnotatedMethods(Pointer.class);
    pointerClass.defineAnnotatedConstants(Pointer.class);
    pointerClass.setReifiedClass(Pointer.class);
    pointerClass.kindOf =
        new RubyModule.KindOf() {
          @Override
          public boolean isKindOf(IRubyObject obj, RubyModule type) {
            return obj instanceof Pointer && super.isKindOf(obj, type);
          }
        };

    module.defineClassUnder(
        "NullPointerError", runtime.getRuntimeError(), runtime.getRuntimeError().getAllocator());

    // Add Pointer::NULL as a constant
    Pointer nullPointer = new Pointer(runtime, pointerClass, new NullMemoryIO(runtime));
    pointerClass.setConstant("NULL", nullPointer);

    runtime
        .getNilClass()
        .addMethod("to_ptr", new NilToPointerMethod(runtime.getNilClass(), nullPointer));

    return pointerClass;
  }
Beispiel #17
0
  public static RubyModule createComparable(Ruby runtime) {
    RubyModule comparableModule = runtime.defineModule("Comparable");
    runtime.setComparable(comparableModule);

    comparableModule.defineAnnotatedMethods(RubyComparable.class);

    return comparableModule;
  }
Beispiel #18
0
 @JRubyMethod(name = "odd?")
 public RubyBoolean odd_p(ThreadContext context) {
   Ruby runtime = context.runtime;
   if (callMethod(context, "%", RubyFixnum.two(runtime)) != RubyFixnum.zero(runtime)) {
     return runtime.getTrue();
   }
   return runtime.getFalse();
 }
Beispiel #19
0
  @JRubyMethod(name = "compatible?", meta = true)
  public static IRubyObject compatible_p(
      ThreadContext context, IRubyObject self, IRubyObject first, IRubyObject second) {
    Ruby runtime = context.runtime;
    Encoding enc = areCompatible(first, second);

    return enc == null ? runtime.getNil() : runtime.getEncodingService().getEncoding(enc);
  }
Beispiel #20
0
  /** Create the ObjectSpace module and add it to the Ruby runtime. */
  public static RubyModule createObjectSpaceModule(Ruby runtime) {
    RubyModule objectSpaceModule = runtime.defineModule("ObjectSpace");
    runtime.setObjectSpaceModule(objectSpaceModule);

    objectSpaceModule.defineAnnotatedMethods(RubyObjectSpace.class);

    return objectSpaceModule;
  }
Beispiel #21
0
  @JRubyMethod(name = "locale_charmap", meta = true)
  public static IRubyObject locale_charmap(ThreadContext context, IRubyObject recv) {
    Ruby runtime = context.runtime;
    EncodingService service = runtime.getEncodingService();
    ByteList name = new ByteList(service.getLocaleEncoding().getName());

    return RubyString.newUsAsciiStringNoCopy(runtime, name);
  }
Beispiel #22
0
 @JRubyMethod(name = "even?")
 public RubyBoolean even_p(ThreadContext context) {
   Ruby runtime = context.getRuntime();
   if (callMethod(context, "%", RubyFixnum.two(runtime)) == RubyFixnum.zero(runtime)) {
     return runtime.getTrue();
   }
   return runtime.getFalse();
 }
Beispiel #23
0
 /** int_chr */
 @JRubyMethod(name = "chr", compat = CompatVersion.RUBY1_8)
 public RubyString chr(ThreadContext context) {
   Ruby runtime = context.getRuntime();
   long value = getLongValue();
   if (value < 0 || value > 0xff)
     throw runtime.newRangeError(this.toString() + " out of char range");
   return RubyString.newStringShared(runtime, SINGLE_CHAR_BYTELISTS[(int) value]);
 }
Beispiel #24
0
  public static DateTimeZone getTimeZone(Ruby runtime, String zone) {
    DateTimeZone cachedZone = runtime.getTimezoneCache().get(zone);

    if (cachedZone != null) return cachedZone;

    String originalZone = zone;
    TimeZone tz = TimeZone.getTimeZone(getEnvTimeZone(runtime).toString());

    // Value of "TZ" property is of a bit different format,
    // which confuses the Java's TimeZone.getTimeZone(id) method,
    // and so, we need to convert it.

    Matcher tzMatcher = TZ_PATTERN.matcher(zone);
    if (tzMatcher.matches()) {
      String sign = tzMatcher.group(2);
      String hours = tzMatcher.group(3);
      String minutes = tzMatcher.group(4);

      // GMT+00:00 --> Etc/GMT, see "MRI behavior"
      // comment below.
      if (("00".equals(hours) || "0".equals(hours))
          && (minutes == null || ":00".equals(minutes) || ":0".equals(minutes))) {
        zone = "Etc/GMT";
      } else {
        // Invert the sign, since TZ format and Java format
        // use opposite signs, sigh... Also, Java API requires
        // the sign to be always present, be it "+" or "-".
        sign = ("-".equals(sign) ? "+" : "-");

        // Always use "GMT" since that's required by Java API.
        zone = "GMT" + sign + hours;

        if (minutes != null) {
          zone += minutes;
        }
      }

      tz = TimeZone.getTimeZone(zone);
    } else {
      if (LONG_TZNAME.containsKey(zone)) tz.setID(LONG_TZNAME.get(zone.toUpperCase()));
    }

    // MRI behavior: With TZ equal to "GMT" or "UTC", Time.now
    // is *NOT* considered as a proper GMT/UTC time:
    //   ENV['TZ']="GMT"
    //   Time.now.gmt? ==> false
    //   ENV['TZ']="UTC"
    //   Time.now.utc? ==> false
    // Hence, we need to adjust for that.
    if ("GMT".equalsIgnoreCase(zone) || "UTC".equalsIgnoreCase(zone)) {
      zone = "Etc/" + zone;
      tz = TimeZone.getTimeZone(zone);
    }

    DateTimeZone dtz = DateTimeZone.forTimeZone(tz);
    runtime.getTimezoneCache().put(originalZone, dtz);
    return dtz;
  }
Beispiel #25
0
  @JRubyMethod(name = "find", meta = true)
  public static IRubyObject find(ThreadContext context, IRubyObject recv, IRubyObject str) {
    Ruby runtime = context.runtime;

    // Wacky but true...return arg if it is an encoding looking for itself
    if (str instanceof RubyEncoding) return str;

    return runtime.getEncodingService().rubyEncodingFromObject(str);
  }
 private synchronized IRubyObject status(Ruby runtime) {
   if (threadImpl.isAlive()) {
     return RubyString.newStringShared(runtime, status.get().bytes);
   } else if (exitingException != null) {
     return runtime.getNil();
   } else {
     return runtime.getFalse();
   }
 }
    public static IRubyObject newLocationArray(Ruby runtime, RubyStackTraceElement[] elements) {
      RubyArray ary = runtime.newArray(elements.length);

      for (RubyStackTraceElement element : elements) {
        ary.append(new RubyThread.Location(runtime, runtime.getLocation(), element));
      }

      return ary;
    }
Beispiel #28
0
 /** rb_dbl2big + LONG2FIX at once (numeric.c) */
 public static IRubyObject dbl2num(Ruby runtime, double val) {
   if (Double.isInfinite(val)) {
     throw runtime.newFloatDomainError(val < 0 ? "-Infinity" : "Infinity");
   }
   if (Double.isNaN(val)) {
     throw runtime.newFloatDomainError("NaN");
   }
   return convertToNum(val, runtime);
 }
  @JRubyMethod(rest = true, visibility = PRIVATE)
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block block) {
    Ruby runtime = getRuntime();
    if (!block.isGiven()) throw runtime.newThreadError("must be called with a block");
    if (threadImpl != null) throw runtime.newThreadError("already initialized thread");

    RubyRunnable runnable = new RubyRunnable(this, args, block);

    return startWith(runnable);
  }
Beispiel #30
0
 @JRubyMethod(rest = true, name = "start", meta = true, compat = RUBY1_9)
 public static RubyThread start19(IRubyObject recv, IRubyObject[] args, Block block) {
   Ruby runtime = recv.getRuntime();
   // The error message may appear incongruous here, due to the difference
   // between JRuby's Thread model and MRI's.
   // We mimic MRI's message in the name of compatibility.
   if (!block.isGiven())
     throw runtime.newArgumentError("tried to create Proc object without a block");
   return startThread(recv, args, false, block);
 }