Пример #1
0
 private static void printErrorPos(ThreadContext context, PrintStream errorStream) {
   if (context.getFile() != null && context.getFile().length() > 0) {
     if (context.getFrameName() != null) {
       errorStream.print(context.getFile() + ":" + context.getLine());
       errorStream.print(":in '" + context.getFrameName() + '\'');
     } else if (context.getLine() != 0) {
       errorStream.print(context.getFile() + ":" + context.getLine());
     } else {
       errorStream.print(context.getFile());
     }
   }
 }
Пример #2
0
  public static IRubyObject INTERPRET_METHOD(
      ThreadContext context,
      CFG cfg,
      InterpreterContext interp,
      String name,
      RubyModule implClass,
      boolean isTraceable) {
    Ruby runtime = interp.getRuntime();
    boolean syntheticMethod = name == null || name.equals("");

    try {
      String className = implClass.getName();
      if (!syntheticMethod)
        ThreadContext.pushBacktrace(context, className, name, context.getFile(), context.getLine());
      if (isTraceable) methodPreTrace(runtime, context, name, implClass);
      return interpret(context, cfg, interp);
    } finally {
      if (isTraceable) {
        try {
          methodPostTrace(runtime, context, name, implClass);
        } finally {
          if (!syntheticMethod) ThreadContext.popBacktrace(context);
        }
      } else {
        if (!syntheticMethod) ThreadContext.popBacktrace(context);
      }
    }
  }
Пример #3
0
  @Override
  public IRubyObject interpret(
      Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
    Block block =
        SharedScopeBlock.newInterpretedSharedScopeClosure(
            context, this, context.getCurrentScope(), self);

    try {
      while (true) {
        try {
          String savedFile = context.getFile();
          int savedLine = context.getLine();

          IRubyObject recv = null;
          try {
            recv = iterNode.interpret(runtime, context, self, aBlock);
          } finally {
            context.setFileAndLine(savedFile, savedLine);
          }

          return callAdapter.call(context, self, recv, block);
        } catch (JumpException.RetryJump rj) {
          // do nothing, allow loop to retry
        }
      }
    } catch (JumpException.BreakJump bj) {
      return (IRubyObject) bj.getValue();
    }
  }
Пример #4
0
  @JRubyMethod(name = "initialize", frame = true, visibility = Visibility.PRIVATE)
  public IRubyObject initialize(ThreadContext context, Block procBlock) {
    if (!procBlock.isGiven()) {
      throw getRuntime().newArgumentError("tried to create Proc object without a block");
    }

    if (isLambda() && procBlock == null) {
      // TODO: warn "tried to create Proc object without a block"
    }

    block = procBlock.cloneBlock();

    if (isThread()) {
      // modify the block with a new backref/lastline-grabbing scope
      StaticScope oldScope = block.getBody().getStaticScope();
      StaticScope newScope =
          new BlockStaticScope(oldScope.getEnclosingScope(), oldScope.getVariables());
      newScope.setBackrefLastlineScope(true);
      newScope.setPreviousCRefScope(oldScope.getPreviousCRefScope());
      newScope.setModule(oldScope.getModule());
      block.getBody().setStaticScope(newScope);
    }

    block.type = type;
    block.setProcObject(this);

    file = context.getFile();
    line = context.getLine();
    return this;
  }
Пример #5
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());
    }
  }
Пример #7
0
  public static IRubyObject[] setupArgs(
      Ruby runtime, ThreadContext context, Node node, IRubyObject self, Block aBlock) {
    if (node == null) return IRubyObject.NULL_ARRAY;

    if (node instanceof ArrayNode) {
      ArrayNode argsArrayNode = (ArrayNode) node;
      String savedFile = context.getFile();
      int savedLine = context.getLine();
      int size = argsArrayNode.size();
      IRubyObject[] argsArray = new IRubyObject[size];

      for (int i = 0; i < size; i++) {
        argsArray[i] = argsArrayNode.get(i).interpret(runtime, context, self, aBlock);
      }

      context.setFileAndLine(savedFile, savedLine);

      return argsArray;
    }

    return ArgsUtil.convertToJavaArray(node.interpret(runtime, context, self, aBlock));
  }
Пример #8
0
  protected static String printBacktraceMRI(RubyException exception) {
    Ruby runtime = exception.getRuntime();
    ThreadContext context = runtime.getCurrentContext();
    IRubyObject backtrace = exception.callMethod(context, "backtrace");

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream errorStream = new PrintStream(baos);
    boolean printedPosition = false;
    if (backtrace.isNil() || !(backtrace instanceof RubyArray)) {
      if (context.getFile() != null && context.getFile().length() > 0) {
        errorStream.print(context.getFile() + ":" + context.getLine());
        printedPosition = true;
      } else {
        errorStream.print(context.getLine());
        printedPosition = true;
      }
    } else if (((RubyArray) backtrace).getLength() == 0) {
      printErrorPos(context, errorStream);
    } else {
      IRubyObject mesg = ((RubyArray) backtrace).first();

      if (mesg.isNil()) {
        printErrorPos(context, errorStream);
      } else {
        errorStream.print(mesg);
        printedPosition = true;
      }
    }

    RubyClass type = exception.getMetaClass();
    String info = exception.toString();

    if (printedPosition) errorStream.print(": ");

    if (type == runtime.getRuntimeError() && (info == null || info.length() == 0)) {
      errorStream.print(": unhandled exception\n");
    } else {
      String path = type.getName();

      if (info.length() == 0) {
        errorStream.print(path + '\n');
      } else {
        if (path.startsWith("#")) {
          path = null;
        }

        String tail = null;
        if (info.indexOf("\n") != -1) {
          tail = info.substring(info.indexOf("\n") + 1);
          info = info.substring(0, info.indexOf("\n"));
        }

        errorStream.print(info);

        if (path != null) {
          errorStream.print(" (" + path + ")\n");
        }

        if (tail != null) {
          errorStream.print(tail + '\n');
        }
      }
    }

    exception.printBacktrace(errorStream);

    return new String(baos.toByteArray());
  }
Пример #9
0
 public static void callTraceFunction(Ruby runtime, ThreadContext context, RubyEvent event) {
   String name = context.getFrameName();
   RubyModule type = context.getFrameKlazz();
   runtime.callEventHooks(context, event, context.getFile(), context.getLine(), name, type);
 }