@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); } }
/** 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"); }
// 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; }
@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(); }