Beispiel #1
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 #2
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;
  }
 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 #5
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);
 }
  @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 #7
0
 @JRubyMethod
 public IRubyObject convpath(ThreadContext context) {
   Ruby runtime = context.runtime;
   EncodingService encodingService = runtime.getEncodingService();
   // we always pass through UTF-16
   IRubyObject utf16Encoding = encodingService.getEncodingList()[UTF16.getIndex()];
   return RubyArray.newArray(
       runtime,
       RubyArray.newArray(runtime, source_encoding(context), utf16Encoding),
       RubyArray.newArray(runtime, utf16Encoding, destination_encoding(context)));
 }
  public static RubyClass createConverterClass(Ruby runtime) {
    RubyClass converterc =
        runtime.defineClassUnder(
            "Converter", runtime.getClass("Data"), CONVERTER_ALLOCATOR, runtime.getEncoding());
    runtime.setConverter(converterc);
    converterc.index = ClassIndex.CONVERTER;
    converterc.setReifiedClass(RubyConverter.class);
    converterc.kindOf = new RubyModule.JavaClassKindOf(RubyConverter.class);

    converterc.defineAnnotatedMethods(RubyConverter.class);
    return converterc;
  }
Beispiel #9
0
  @JRubyMethod(visibility = PRIVATE)
  public IRubyObject initialize(
      ThreadContext context, IRubyObject src, IRubyObject dest, IRubyObject _opt) {
    Ruby runtime = context.runtime;
    EncodingService encodingService = runtime.getEncodingService();

    // both may be null
    Encoding srcEncoding = encodingService.getEncodingFromObjectNoError(src);
    Encoding destEncoding = encodingService.getEncodingFromObjectNoError(dest);

    int flags = 0;
    IRubyObject replace = context.nil;

    if (srcEncoding == destEncoding && srcEncoding != null) {
      throw runtime.newConverterNotFoundError(
          "code converter not found (" + srcEncoding + " to " + destEncoding + ")");
    }

    // Ensure we'll be able to get charsets fo these encodings
    try {
      if (srcEncoding != destEncoding) {
        if (srcEncoding != null) encodingService.charsetForEncoding(srcEncoding);
        if (destEncoding != null) encodingService.charsetForEncoding(destEncoding);
      }
    } catch (RaiseException e) {
      if (e.getException().getMetaClass().getBaseName().equals("CompatibilityError")) {
        throw runtime.newConverterNotFoundError(
            "code converter not found (" + srcEncoding + " to " + destEncoding + ")");
      } else {
        throw e;
      }
    }

    if (!_opt.isNil()) {
      if (_opt instanceof RubyHash) {
        RubyHash opt = (RubyHash) _opt;
        flags |= EncodingUtils.econvPrepareOpts(context, opt, new IRubyObject[] {opt});

        IRubyObject value = opt.fastARef(runtime.newSymbol("replace"));
        if (value != null) {
          replace = value;
        }
      } else {
        flags = (int) _opt.convertToInteger().getLongValue();
        replace = context.nil;
      }
    }

    transcoder = new CharsetTranscoder(context, destEncoding, srcEncoding, flags, replace);

    return context.runtime.getNil();
  }
Beispiel #10
0
  @JRubyMethod(name = "pass", meta = true)
  public static IRubyObject pass(IRubyObject recv) {
    Ruby runtime = recv.getRuntime();
    ThreadService ts = runtime.getThreadService();
    boolean critical = ts.getCritical();

    ts.setCritical(false);

    Thread.yield();

    ts.setCritical(critical);

    return recv.getRuntime().getNil();
  }
Beispiel #11
0
  public void exceptionRaised(RaiseException exception) {
    assert isCurrent();

    RubyException rubyException = exception.getException();
    Ruby runtime = rubyException.getRuntime();
    if (runtime.getSystemExit().isInstance(rubyException)) {
      runtime
          .getThreadService()
          .getMainThread()
          .raise(new IRubyObject[] {rubyException}, Block.NULL_BLOCK);
    } else if (abortOnException(runtime)) {
      RubyException systemExit;

      if (!runtime.is1_9()) {
        runtime.printError(rubyException);

        systemExit = RubySystemExit.newInstance(runtime, 1);
        systemExit.message = rubyException.message;
        systemExit.set_backtrace(rubyException.backtrace());
      } else {
        systemExit = rubyException;
      }

      runtime
          .getThreadService()
          .getMainThread()
          .raise(new IRubyObject[] {systemExit}, Block.NULL_BLOCK);
      return;
    } else if (runtime.getDebug().isTrue()) {
      runtime.printError(exception.getException());
    }
    exitingException = exception;
  }
Beispiel #12
0
  private static RubyThread adoptThread(final IRubyObject recv, Thread t, Block block) {
    final Ruby runtime = recv.getRuntime();
    final RubyThread rubyThread = new RubyThread(runtime, (RubyClass) recv);

    rubyThread.threadImpl = new NativeThread(rubyThread, t);
    ThreadContext context = runtime.getThreadService().registerNewThread(rubyThread);
    runtime.getThreadService().associateThread(t, rubyThread);

    context.preAdoptThread();

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

    return rubyThread;
  }
Beispiel #13
0
  /**
   * For handling all non-Ruby exceptions bubbling out of threads
   *
   * @param exception
   */
  @SuppressWarnings("deprecation")
  public void exceptionRaised(Throwable exception) {
    if (exception instanceof RaiseException) {
      exceptionRaised((RaiseException) exception);
      return;
    }

    assert isCurrent();

    Ruby runtime = getRuntime();
    if (abortOnException(runtime) && exception instanceof Error) {
      // re-propagate on main thread
      runtime.getThreadService().getMainThread().getNativeThread().stop(exception);
    } else {
      // just rethrow on this thread, let system handlers report it
      UnsafeFactory.getUnsafe().throwException(exception);
    }
  }
Beispiel #14
0
  private IRubyObject symbolFromResult(
      RubyCoderResult result, Ruby runtime, int flags, ThreadContext context) {
    if (result != null) {
      return runtime.newSymbol(result.stringResult);
    }

    if ((flags & PARTIAL_INPUT) == 0) {
      return context.runtime.newSymbol("finished");
    } else {
      return context.runtime.newSymbol("source_buffer_empty");
    }
  }
Beispiel #15
0
  @JRubyMethod(optional = 3)
  public IRubyObject raise(IRubyObject[] args, Block block) {
    Ruby runtime = getRuntime();
    ThreadContext context = runtime.getCurrentContext();
    if (this == context.getThread()) {
      return RubyKernel.raise(context, runtime.getKernel(), args, block);
    }

    debug(this, "before raising");
    RubyThread currentThread = getRuntime().getCurrentContext().getThread();

    debug(this, "raising");
    IRubyObject exception = prepareRaiseException(runtime, args, block);

    runtime
        .getThreadService()
        .deliverEvent(
            new ThreadService.Event(
                currentThread, this, ThreadService.Event.Type.RAISE, exception));

    return this;
  }
Beispiel #16
0
  @JRubyMethod(compat = RUBY1_9, meta = true)
  public static IRubyObject asciicompat_encoding(
      ThreadContext context, IRubyObject self, IRubyObject strOrEnc) {
    Ruby runtime = context.runtime;
    EncodingService encodingService = runtime.getEncodingService();

    Encoding encoding = encodingService.getEncodingFromObjectNoError(strOrEnc);

    if (encoding == null) {
      return context.nil;
    }

    if (encoding.isAsciiCompatible()) {
      return context.nil;
    }

    Encoding asciiCompat = NONASCII_TO_ASCII.get(encoding);

    if (asciiCompat == null) {
      throw runtime.newConverterNotFoundError("no ASCII compatible encoding found for " + strOrEnc);
    }

    return encodingService.convertEncodingToRubyEncoding(asciiCompat);
  }
Beispiel #17
0
  @JRubyMethod(compat = RUBY1_9)
  public IRubyObject primitive_errinfo(ThreadContext context) {
    Ruby runtime = context.runtime;

    RubyCoderResult lastResult = transcoder.getLastResult();

    // if we have not done anything, produce an empty errinfo
    if (lastResult == null) {
      return runtime.newArray(
          new IRubyObject[] {
            runtime.newSymbol("source_buffer_empty"),
            context.nil,
            context.nil,
            context.nil,
            context.nil
          });
    }

    RubyArray errinfo = RubyArray.newArray(context.runtime);

    if (!lastResult.isError()) {
      return runtime.newArray(
          new IRubyObject[] {
            runtime.newSymbol(lastResult.stringResult),
            context.nil,
            context.nil,
            context.nil,
            context.nil
          });
    } else {
      errinfo.append(runtime.newSymbol(lastResult.stringResult));

      // FIXME: gross
      errinfo.append(RubyString.newString(runtime, lastResult.inEncoding.getName()));
      errinfo.append(RubyString.newString(runtime, lastResult.outEncoding.getName()));

      if (lastResult.isError() && lastResult.errorBytes != null) {
        // FIXME: do this elsewhere and cache it
        ByteList errorBytes = new ByteList(lastResult.errorBytes, lastResult.inEncoding, true);
        errinfo.append(RubyString.newString(runtime, errorBytes));
      } else {
        errinfo.append(RubyString.newEmptyString(runtime));
      }

      if (lastResult.readagainBytes != null) {
        // FIXME: do this elsewhere and cache it
        ByteList readagainBytes =
            new ByteList(lastResult.readagainBytes, lastResult.inEncoding, true);
        errinfo.append(RubyString.newString(runtime, readagainBytes));
      } else {
        errinfo.append(RubyString.newEmptyString(runtime));
      }
    }

    return errinfo;
  }
Beispiel #18
0
  @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");

    try {
      RubyRunnable runnable = new RubyRunnable(this, args, context.getFrames(0), block);
      if (RubyInstanceConfig.POOLING_ENABLED) {
        FutureThread futureThread = new FutureThread(this, runnable);
        threadImpl = futureThread;

        addToCorrectThreadGroup(context);

        threadImpl.start();

        // JRUBY-2380, associate future early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(futureThread.getFuture(), this);
      } else {
        Thread thread = new Thread(runnable);
        thread.setDaemon(true);
        thread.setName(
            "Ruby" + thread.getName() + ": " + context.getFile() + ":" + (context.getLine() + 1));
        threadImpl = new NativeThread(this, thread);

        addToCorrectThreadGroup(context);

        // JRUBY-2380, associate thread early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(thread, this);

        threadImpl.start();
      }

      // We yield here to hopefully permit the target thread to schedule
      // MRI immediately schedules it, so this is close but not exact
      Thread.yield();

      return this;
    } catch (OutOfMemoryError oome) {
      if (oome.getMessage().equals("unable to create new native thread")) {
        throw runtime.newThreadError(oome.getMessage());
      }
      throw oome;
    } catch (SecurityException ex) {
      throw runtime.newThreadError(ex.getMessage());
    }
  }
  private IRubyObject startWith(ThreadedRunnable runnable) throws RaiseException, OutOfMemoryError {
    Ruby runtime = getRuntime();
    ThreadContext context = runtime.getCurrentContext();

    try {
      if (RubyInstanceConfig.POOLING_ENABLED) {
        FutureThread futureThread = new FutureThread(this, runnable);
        threadImpl = futureThread;

        addToCorrectThreadGroup(context);

        threadImpl.start();

        // JRUBY-2380, associate future early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(futureThread.getFuture(), this);
      } else {
        Thread thread = new Thread(runnable);
        thread.setDaemon(true);
        thread.setName(
            "Ruby" + thread.getName() + ": " + context.getFile() + ":" + (context.getLine() + 1));
        threadImpl = new NativeThread(this, thread);

        addToCorrectThreadGroup(context);

        // JRUBY-2380, associate thread early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(thread, this);

        threadImpl.start();
      }

      // We yield here to hopefully permit the target thread to schedule
      // MRI immediately schedules it, so this is close but not exact
      Thread.yield();

      return this;
    } catch (OutOfMemoryError oome) {
      if (oome.getMessage().equals("unable to create new native thread")) {
        throw runtime.newThreadError(oome.getMessage());
      }
      throw oome;
    } catch (SecurityException ex) {
      throw runtime.newThreadError(ex.getMessage());
    }
  }
Beispiel #20
0
  private IRubyObject prepareRaiseException(Ruby runtime, IRubyObject[] args, Block block) {
    if (args.length == 0) {
      IRubyObject lastException = errorInfo;
      if (lastException.isNil()) {
        return new RaiseException(runtime, runtime.getRuntimeError(), "", false).getException();
      }
      return lastException;
    }

    IRubyObject exception;
    ThreadContext context = getRuntime().getCurrentContext();

    if (args.length == 1) {
      if (args[0] instanceof RubyString) {
        return runtime.getRuntimeError().newInstance(context, args, block);
      }

      if (!args[0].respondsTo("exception")) {
        return runtime.newTypeError("exception class/object expected").getException();
      }
      exception = args[0].callMethod(context, "exception");
    } else {
      if (!args[0].respondsTo("exception")) {
        return runtime.newTypeError("exception class/object expected").getException();
      }

      exception = args[0].callMethod(context, "exception", args[1]);
    }

    if (!runtime.getException().isInstance(exception)) {
      return runtime.newTypeError("exception object expected").getException();
    }

    if (args.length == 3) {
      ((RubyException) exception).set_backtrace(args[2]);
    }

    return exception;
  }
Beispiel #21
0
 public static final Pointer getNull(Ruby runtime) {
   return runtime.getFFI().nullPointer;
 }
Beispiel #22
0
  @JRubyMethod(name = "join", optional = 1)
  public IRubyObject join(IRubyObject[] args) {
    Ruby runtime = getRuntime();
    long timeoutMillis = Long.MAX_VALUE;

    if (args.length > 0 && !args[0].isNil()) {
      if (args.length > 1) {
        throw getRuntime().newArgumentError(args.length, 1);
      }
      // MRI behavior: value given in seconds; converted to Float; less
      // than or equal to zero returns immediately; returns nil
      timeoutMillis = (long) (1000.0D * args[0].convertToFloat().getValue());
      if (timeoutMillis <= 0) {
        // TODO: not sure that we should skip calling join() altogether.
        // Thread.join() has some implications for Java Memory Model, etc.
        if (threadImpl.isAlive()) {
          return getRuntime().getNil();
        } else {
          return this;
        }
      }
    }

    if (isCurrent()) {
      throw getRuntime().newThreadError("thread " + identityString() + " tried to join itself");
    }

    try {
      if (runtime.getThreadService().getCritical()) {
        // If the target thread is sleeping or stopped, wake it
        synchronized (this) {
          notify();
        }

        // interrupt the target thread in case it's blocking or waiting
        // WARNING: We no longer interrupt the target thread, since this usually means
        // interrupting IO and with NIO that means the channel is no longer usable.
        // We either need a new way to handle waking a target thread that's waiting
        // on IO, or we need to accept that we can't wake such threads and must wait
        // for them to complete their operation.
        // threadImpl.interrupt();
      }

      RubyThread currentThread = getRuntime().getCurrentContext().getThread();
      final long timeToWait = Math.min(timeoutMillis, 200);

      // We need this loop in order to be able to "unblock" the
      // join call without actually calling interrupt.
      long start = System.currentTimeMillis();
      while (true) {
        currentThread.pollThreadEvents();
        threadImpl.join(timeToWait);
        if (!threadImpl.isAlive()) {
          break;
        }
        if (System.currentTimeMillis() - start > timeoutMillis) {
          break;
        }
      }
    } catch (InterruptedException ie) {
      ie.printStackTrace();
      assert false : ie;
    } catch (ExecutionException ie) {
      ie.printStackTrace();
      assert false : ie;
    }

    if (exitingException != null) {
      // Set $! in the current thread before exiting
      getRuntime().getGlobalVariables().set("$!", (IRubyObject) exitingException.getException());
      throw exitingException;
    }

    if (threadImpl.isAlive()) {
      return getRuntime().getNil();
    } else {
      return this;
    }
  }
Beispiel #23
0
 public RubyConverter(Ruby runtime) {
   super(runtime, runtime.getConverter());
 }
Beispiel #24
0
 /**
  * Returns the status of the global ``abort on exception'' condition. The default is false. When
  * set to true, will cause all threads to abort (the process will exit(0)) if an exception is
  * raised in any thread. See also Thread.abort_on_exception= .
  */
 @JRubyMethod(name = "abort_on_exception", meta = true)
 public static RubyBoolean abort_on_exception_x(IRubyObject recv) {
   Ruby runtime = recv.getRuntime();
   return runtime.isGlobalAbortOnExceptionEnabled() ? runtime.getTrue() : runtime.getFalse();
 }
Beispiel #25
0
  @JRubyMethod(required = 2, optional = 4)
  public IRubyObject primitive_convert(ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.runtime;

    RubyString input;
    RubyString output;
    int outputByteoffset = -1;
    int outputBytesize = 0;
    int flags = 0;

    int hashArg = -1;

    if (args.length > 2 && !args[2].isNil()) {
      if (args.length == 3 && args[2] instanceof RubyHash) {
        hashArg = 2;
      } else {
        outputByteoffset = (int) args[2].convertToInteger().getLongValue();
        if (outputByteoffset < 0) throw runtime.newArgumentError("negative offset");
      }
    }

    if (args.length > 3 && !args[3].isNil()) {
      if (args.length == 4 && args[3] instanceof RubyHash) {
        hashArg = 3;
      } else {
        outputBytesize = (int) args[3].convertToInteger().getLongValue();
        if (outputBytesize < 0) throw runtime.newArgumentError("negative bytesize");
      }
    }

    if (args.length > 4 && !args[4].isNil()) {
      if (args.length > 5 && !args[5].isNil()) {
        throw runtime.newArgumentError(args.length, 5);
      }

      if (args[4] instanceof RubyHash) {
        hashArg = 4;
      } else {
        flags = (int) args[4].convertToInteger().getLongValue();
      }
    }

    IRubyObject opt = context.nil;
    if (hashArg != -1 && !(opt = TypeConverter.checkHashType(runtime, args[hashArg])).isNil()) {
      IRubyObject v = ((RubyHash) opt).op_aref(context, runtime.newSymbol("partial_input"));
      if (v.isTrue()) {
        flags |= EncodingUtils.ECONV_PARTIAL_INPUT;
      }
      v = ((RubyHash) opt).op_aref(context, runtime.newSymbol("after_output"));
      if (v.isTrue()) {
        flags |= EncodingUtils.ECONV_AFTER_OUTPUT;
      }
    } else {
      flags = 0;
    }

    ByteList inBytes;
    ByteList outBytes;

    if (args[0].isNil()) {
      inBytes = new ByteList();
    } else {
      input = args[0].convertToString();
      input.modify19();
      inBytes = input.getByteList();
    }

    output = args[1].convertToString();
    output.modify19();
    outBytes = output.getByteList();

    if (outputByteoffset == -1) {
      outputByteoffset = outBytes.getRealSize();
    } else if (outputByteoffset > outBytes.getRealSize()) {
      throw runtime.newArgumentError("offset too big");
    }

    int outputByteEnd = outputByteoffset + outputBytesize;

    if (outputByteEnd > outBytes.getRealSize()) {
      outBytes.ensure(outputByteEnd);
    }

    RubyCoderResult result =
        transcoder.primitiveConvert(
            context,
            inBytes,
            output.getByteList(),
            outputByteoffset,
            outputBytesize,
            inBytes.getEncoding(),
            inBytes.getEncoding().isAsciiCompatible(),
            flags);

    outBytes.setEncoding(
        transcoder.outEncoding != null ? transcoder.outEncoding : inBytes.getEncoding());

    return symbolFromResult(result, runtime, flags, context);
  }
Beispiel #26
0
  protected RubyThread(Ruby runtime, RubyClass type) {
    super(runtime, type);

    finalResult = runtime.getNil();
    errorInfo = runtime.getNil();
  }
Beispiel #27
0
 public Pointer(Ruby runtime, RubyClass klazz) {
   super(runtime, klazz, runtime.getFFI().getNullMemoryIO(), 0);
 }
Beispiel #28
0
 public static final RubyClass getPointerClass(Ruby runtime) {
   return runtime.getFFI().pointerClass;
 }
Beispiel #29
0
 private boolean abortOnException(Ruby runtime) {
   return (runtime.isGlobalAbortOnExceptionEnabled() || abortOnException);
 }