Example #1
0
  @JRubyMethod(
      name = "raise",
      optional = 3,
      frame = true,
      module = true,
      visibility = Visibility.PRIVATE,
      omit = true)
  public static IRubyObject rbRaise(
      ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) {
    Ruby runtime = context.runtime;

    // Check for a Java exception
    ConcreteJavaProxy exception = null;
    if (args.length == 0 && runtime.getGlobalVariables().get("$!") instanceof ConcreteJavaProxy) {
      exception = (ConcreteJavaProxy) runtime.getGlobalVariables().get("$!");
    } else if (args.length == 1 && args[0] instanceof ConcreteJavaProxy) {
      exception = (ConcreteJavaProxy) args[0];
    }

    if (exception != null) {
      // looks like someone's trying to raise a Java exception. Let them.
      Object maybeThrowable = exception.getObject();

      if (maybeThrowable instanceof Throwable) {
        // yes, we're cheating here.
        Helpers.throwException((Throwable) maybeThrowable);
        return recv; // not reached
      } else {
        throw runtime.newTypeError("can't raise a non-Throwable Java object");
      }
    } else {
      return RubyKernel.raise(context, recv, args, block);
    }
  }
Example #2
0
  /** Compatibility with Tempfile#make_tmpname(basename, n) in MRI */
  @JRubyMethod(visibility = PRIVATE)
  public IRubyObject make_tmpname(
      ThreadContext context, IRubyObject basename, IRubyObject n, Block block) {
    Ruby runtime = context.getRuntime();
    IRubyObject[] newargs = new IRubyObject[5];

    IRubyObject base, suffix;
    if (basename instanceof RubyArray) {
      RubyArray array = (RubyArray) basename;
      int length = array.getLength();

      base = length > 0 ? array.eltInternal(0) : runtime.getNil();
      suffix = length > 0 ? array.eltInternal(1) : runtime.getNil();
    } else {
      base = basename;
      suffix = runtime.newString("");
    }

    newargs[0] = runtime.newString("%s.%d.%d%s");
    newargs[1] = base;
    newargs[2] = runtime.getGlobalVariables().get("$$"); // PID
    newargs[3] = n;
    newargs[4] = suffix;
    return callMethod(context, "sprintf", newargs);
  }
  @JRubyMethod(name = "print", rest = true, compat = CompatVersion.RUBY1_9)
  @Override
  public IRubyObject print19(ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.runtime;
    if (args.length != 0) {
      for (int i = 0, j = args.length; i < j; i++) {
        append(context, args[i]);
      }
    } else {
      IRubyObject arg = runtime.getGlobalVariables().get("$_");
      append(context, arg.isNil() ? RubyString.newEmptyString(getRuntime()) : arg);
    }
    IRubyObject sep = runtime.getGlobalVariables().get("$\\");
    if (!sep.isNil()) append(context, sep);

    return runtime.getNil();
  }
  @JRubyMethod(name = "print", rest = true)
  @Override
  public IRubyObject print(ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.runtime;
    if (args.length != 0) {
      for (int i = 0, j = args.length; i < j; i++) {
        append(context, args[i]);
      }
    } else {
      IRubyObject arg = runtime.getGlobalVariables().get("$_");
      append(
          context,
          arg.isNil() ? makeString(runtime, new ByteList(new byte[] {'n', 'i', 'l'})) : arg);
    }
    IRubyObject sep = runtime.getGlobalVariables().get("$\\");
    if (!sep.isNil()) append(context, sep);

    return runtime.getNil();
  }
  @Test
  public void shouldWrapJavaIOExceptions() throws Exception {
    Ruby ruby = Ruby.newInstance();
    RackInput rackInput = mock(RackInput.class);
    when(rackInput.read(null)).thenThrow(new IOException("fake"));

    JRubyRackInput subject = new JRubyRackInput(ruby, rackInput);
    GlobalVariables globalVariables = ruby.getGlobalVariables();
    globalVariables.set("$rack_input", subject);

    IRubyObject result =
        ruby.evalScriptlet(
            "begin; $rack_input.read; rescue IOError => e; \"rescued #{e.message}\"; end");
    assertThat(result.asJavaString()).isEqualTo("rescued fake");
  }
Example #6
0
  // strio_getline
  private IRubyObject getline(ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.runtime;

    IRubyObject str = context.nil;
    ;
    int n, limit = -1;

    switch (args.length) {
      case 0:
        str = runtime.getGlobalVariables().get("$/");
        break;

      case 1:
        {
          str = args[0];
          if (!str.isNil() && !(str instanceof RubyString)) {
            IRubyObject tmp = str.checkStringType19();
            if (tmp.isNil()) {
              limit = RubyNumeric.num2int(str);
              if (limit == 0) return runtime.newString();
              str = runtime.getGlobalVariables().get("$/");
            } else {
              str = tmp;
            }
          }
          break;
        }

      case 2:
        if (!args[0].isNil()) str = args[0].convertToString();
        // 2.0 ignores double nil, 1.9 raises
        if (runtime.is2_0()) {
          if (!args[1].isNil()) {
            limit = RubyNumeric.num2int(args[1]);
          }
        } else {
          limit = RubyNumeric.num2int(args[1]);
        }
        break;
    }

    if (isEndOfString()) {
      return context.nil;
    }

    ByteList dataByteList = ptr.string.getByteList();
    byte[] dataBytes = dataByteList.getUnsafeBytes();
    int begin = dataByteList.getBegin();
    int s = begin + ptr.pos;
    int e = begin + dataByteList.getRealSize();
    int p;

    if (limit > 0 && s + limit < e) {
      e = dataByteList.getEncoding().rightAdjustCharHead(dataBytes, s, s + limit, e);
    }
    if (str.isNil()) {
      str = strioSubstr(runtime, ptr.pos, e - s);
    } else if ((n = ((RubyString) str).size()) == 0) {
      // this is not an exact port; the original confused me
      p = s;
      // remove leading \n
      while (dataBytes[p] == '\n') {
        if (++p == e) {
          return context.nil;
        }
      }
      s = p;
      // find next \n or end; if followed by \n, include it too
      p = memchr(dataBytes, p, '\n', e - p);
      if (p != -1) {
        if (++p < e && dataBytes[p] == '\n') {
          e = p + 1;
        } else {
          e = p;
        }
      }
      str = strioSubstr(runtime, s - begin, e - s);
    } else if (n == 1) {
      RubyString strStr = (RubyString) str;
      ByteList strByteList = strStr.getByteList();
      if ((p = memchr(dataBytes, s, strByteList.get(0), e - s)) != -1) {
        e = p + 1;
      }
      str = strioSubstr(runtime, ptr.pos, e - s);
    } else {
      if (n < e - s) {
        RubyString strStr = (RubyString) str;
        ByteList strByteList = strStr.getByteList();
        byte[] strBytes = strByteList.getUnsafeBytes();

        int[] skip = new int[1 << CHAR_BIT];
        int pos;
        p = strByteList.getBegin();
        bm_init_skip(skip, strBytes, p, n);
        if ((pos = bm_search(strBytes, p, n, dataBytes, s, e - s, skip)) >= 0) {
          e = s + pos + n;
        }
      }
      str = strioSubstr(runtime, ptr.pos, e - s);
    }
    ptr.pos = e - begin;
    ptr.lineno++;
    return str;
  }
Example #7
0
  @Override
  public Label interpret(InterpreterContext interp) {
    String name;
    Object receiver;
    Ruby rt = interp.getRuntime();
    Object rVal = null;

    switch (this.implMethod) {
        // SSS FIXME: Note that compiler/impl/BaseBodyCompiler is using op_match2 for match() and
        // and op_match for match2,
        // and we are replicating it here ... Is this a bug there?
      case MATCH:
        receiver = getReceiver().retrieve(interp);
        rVal = ((RubyRegexp) receiver).op_match2(interp.getContext());
        break;
      case MATCH2:
        receiver = getReceiver().retrieve(interp);
        rVal =
            ((RubyRegexp) receiver)
                .op_match(interp.getContext(), (IRubyObject) getCallArgs()[0].retrieve(interp));
        break;
      case MATCH3:
        { // ENEBO: Only for rubystring?
          receiver = getReceiver().retrieve(interp);
          IRubyObject value = (IRubyObject) getCallArgs()[0].retrieve(interp);

          if (value instanceof RubyString) {
            rVal = ((RubyRegexp) receiver).op_match(interp.getContext(), value);
          } else {
            rVal = value.callMethod(interp.getContext(), "=~", (IRubyObject) receiver);
          }
          break;
        }
      case SET_WITHIN_DEFINED:
        interp.getContext().setWithinDefined(((BooleanLiteral) getCallArgs()[0]).isTrue());
        break;
      case RTH_GET_DEFINED_CONSTANT_OR_BOUND_METHOD:
        {
          IRubyObject v = (IRubyObject) getCallArgs()[0].retrieve(interp);
          name = ((StringLiteral) getCallArgs()[1])._str_value;
          ByteList definedType = RuntimeHelpers.getDefinedConstantOrBoundMethod(v, name);
          rVal =
              (definedType == null ? Nil.NIL : (new StringLiteral(definedType))).retrieve(interp);
          break;
        }
      case BLOCK_GIVEN:
        rVal = rt.newBoolean(interp.getBlock().isGiven());
        break;
      case RT_IS_GLOBAL_DEFINED:
        // name = getCallArgs()[0].retrieve(interp).toString();
        name = ((StringLiteral) getCallArgs()[0])._str_value;
        rVal = rt.newBoolean(rt.getGlobalVariables().isDefined(name));
        break;
      case RT_GET_OBJECT:
        rVal = rt.getObject();
        break;
      case RT_GET_BACKREF:
        // SSS: FIXME: Or use this directly? "context.getCurrentScope().getBackRef(rt)" What is the
        // diff??
        rVal = RuntimeHelpers.getBackref(rt, interp.getContext());
        break;
      case SELF_METACLASS:
        rVal = ((IRubyObject) getReceiver().retrieve(interp)).getMetaClass();
        break;
      case CHECK_ARITY:
        {
          Operand[] args = getCallArgs();
          int required = ((Fixnum) args[0]).value.intValue();
          int opt = ((Fixnum) args[1]).value.intValue();
          int rest = ((Fixnum) args[2]).value.intValue();
          int numArgs = interp.getParameterCount();
          if ((numArgs < required) || ((rest == -1) && (numArgs > (required + opt)))) {
            Arity.raiseArgumentError(interp.getRuntime(), numArgs, required, required + opt);
          }
          break;
        }
      case RAISE_ARGUMENT_ERROR:
        {
          Operand[] args = getCallArgs();
          int required = ((Fixnum) args[0]).value.intValue();
          int opt = ((Fixnum) args[1]).value.intValue();
          int rest = ((Fixnum) args[2]).value.intValue();
          int numArgs = ((Fixnum) args[3]).value.intValue();
          Arity.raiseArgumentError(interp.getRuntime(), numArgs, required, required + opt);
          break;
        }
      case SELF_HAS_INSTANCE_VARIABLE:
        {
          receiver = getReceiver().retrieve(interp);
          // name = getCallArgs()[0].retrieve(interp).toString();
          name = ((StringLiteral) getCallArgs()[0])._str_value;
          rVal =
              rt.newBoolean(
                  ((IRubyObject) receiver).getInstanceVariables().hasInstanceVariable(name));
          break;
        }
      case SELF_IS_METHOD_BOUND:
        {
          receiver = getReceiver().retrieve(interp);
          boolean bound =
              ((IRubyObject) receiver)
                  .getMetaClass()
                  .isMethodBound(((StringLiteral) getCallArgs()[0])._str_value, false);
          rVal = rt.newBoolean(bound);
          break;
        }
      case TC_SAVE_ERR_INFO:
        rVal = interp.getContext().getErrorInfo();
        break;
      case TC_RESTORE_ERR_INFO:
        interp.getContext().setErrorInfo((IRubyObject) getCallArgs()[0].retrieve(interp));
        break;
      case TC_GET_CONSTANT_DEFINED:
        // name = getCallArgs()[0].retrieve(interp).toString();
        name = ((StringLiteral) getCallArgs()[0])._str_value;
        rVal = rt.newBoolean(interp.getContext().getConstantDefined(name));
        break;
      case TC_GET_CURRENT_MODULE:
        rVal = interp.getContext().getCurrentScope().getStaticScope().getModule();
        break;
      case BACKREF_IS_RUBY_MATCH_DATA:
        // bRef = getBackref()
        // flag = bRef instanceof RubyMatchData
        try {
          // SSS: FIXME: Or use this directly? "context.getCurrentScope().getBackRef(rt)" What is
          // the diff??
          IRubyObject bRef = RuntimeHelpers.getBackref(rt, interp.getContext());
          rVal =
              rt.newBoolean(
                  Class.forName("RubyMatchData").isInstance(bRef)); // SSS FIXME: Is this correct?
        } catch (ClassNotFoundException e) {
          // Should never get here!
          throw new RuntimeException(e);
        }
        break;
      case METHOD_PUBLIC_ACCESSIBLE:
        {
          /* ------------------------------------------------------------
           * mc = r.metaClass
           * v  = mc.getVisibility(methodName)
           * v.isPrivate? || (v.isProtected? && receiver/self? instanceof mc.getRealClass)
           * ------------------------------------------------------------ */
          IRubyObject r = (IRubyObject) getReceiver().retrieve(interp);
          RubyClass mc = r.getMetaClass();
          String arg = ((StringLiteral) getCallArgs()[0])._str_value;
          Visibility v = mc.searchMethod(arg).getVisibility();
          rVal =
              rt.newBoolean(
                  (v != null)
                      && !v.isPrivate()
                      && !(v.isProtected() && mc.getRealClass().isInstance(r)));
          break;
        }
      case CLASS_VAR_DEFINED:
        {
          // cm.classVarDefined(name) || (cm.isSingleton && !(cm.attached instanceof RubyModule) &&
          // cm.attached.classVarDefined(name))
          boolean flag;
          RubyModule cm = (RubyModule) getReceiver().retrieve(interp);
          name = ((StringLiteral) getCallArgs()[0])._str_value;
          flag = cm.isClassVarDefined(name);
          if (!flag) {
            if (cm.isSingleton()) {
              IRubyObject ao = ((MetaClass) cm).getAttached();
              if (ao instanceof RubyModule) flag = ((RubyModule) ao).isClassVarDefined(name);
            }
          }
          rVal = rt.newBoolean(flag);
          break;
        }
      case FRAME_SUPER_METHOD_BOUND:
        {
          receiver = getReceiver().retrieve(interp);
          boolean flag = false;
          ThreadContext tc = interp.getContext();
          String fn = tc.getFrameName();
          if (fn != null) {
            RubyModule fc = tc.getFrameKlazz();
            if (fc != null) {
              flag =
                  RuntimeHelpers.findImplementerIfNecessary(
                          ((IRubyObject) receiver).getMetaClass(), fc)
                      .getSuperClass()
                      .isMethodBound(fn, false);
            }
          }
          rVal = rt.newBoolean(flag);
          break;
        }
    }

    // Store the result
    if (rVal != null) getResult().store(interp, rVal);

    return null;
  }
  private IRubyObject internalGets(ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.runtime;

    if (!isEndOfString() && !data.eof) {
      boolean isParagraph = false;
      boolean is19 = runtime.is1_9();
      ByteList sep = ((RubyString) runtime.getGlobalVariables().get("$/")).getByteList();
      IRubyObject sepArg;
      int limit = -1;

      if (is19) {
        IRubyObject limitArg =
            (args.length > 1
                ? args[1]
                : (args.length > 0 && args[0] instanceof RubyFixnum ? args[0] : null));
        if (limitArg != null) {
          limit = RubyNumeric.fix2int(limitArg);
        }

        sepArg = (args.length > 0 && !(args[0] instanceof RubyFixnum) ? args[0] : null);
      } else {
        sepArg = (args.length > 0 ? args[0] : null);
      }

      if (sepArg != null) {
        if (sepArg.isNil()) {
          int bytesAvailable = data.internal.getByteList().getRealSize() - (int) data.pos;
          int bytesToUse = (limit < 0 || limit >= bytesAvailable ? bytesAvailable : limit);
          ByteList buf = data.internal.getByteList().makeShared((int) data.pos, bytesToUse);
          data.pos += buf.getRealSize();
          return makeString(runtime, buf);
        }

        sep = sepArg.convertToString().getByteList();
        if (sep.getRealSize() == 0) {
          isParagraph = true;
          sep = Stream.PARAGRAPH_SEPARATOR;
        }
      }

      ByteList ss = data.internal.getByteList();

      if (isParagraph) {
        swallowLF(ss);
        if (data.pos == ss.getRealSize()) {
          return runtime.getNil();
        }
      }

      int ix = ss.indexOf(sep, (int) data.pos);

      ByteList add;
      if (-1 == ix) {
        ix = data.internal.getByteList().getRealSize();
        add = ByteList.EMPTY_BYTELIST;
      } else {
        add = sep;
      }

      int bytes = ix - (int) data.pos;
      int bytesToUse = (limit < 0 || limit >= bytes ? bytes : limit);

      int bytesWithSep = ix - (int) data.pos + add.getRealSize();
      int bytesToUseWithSep = (limit < 0 || limit >= bytesWithSep ? bytesWithSep : limit);

      ByteList line = new ByteList(bytesToUseWithSep);
      if (is19) line.setEncoding(data.internal.getByteList().getEncoding());
      line.append(data.internal.getByteList(), (int) data.pos, bytesToUse);
      data.pos += bytesToUse;

      int sepBytesToUse = bytesToUseWithSep - bytesToUse;
      line.append(add, 0, sepBytesToUse);
      data.pos += sepBytesToUse;

      if (sepBytesToUse >= add.getRealSize()) {
        data.lineno++;
      }

      return makeString(runtime, line);
    }
    return runtime.getNil();
  }