/** 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); }
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; }
@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; }
@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; }
@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); }
@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); }
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; }
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; }
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(); } }
@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); }
@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); }
@JRubyMethod(name = "default_internal=", required = 1, meta = true, compat = RUBY1_9) public static IRubyObject setDefaultInternal(IRubyObject recv, IRubyObject encoding) { Ruby runtime = recv.getRuntime(); EncodingService service = runtime.getEncodingService(); if (encoding.isNil()) { recv.getRuntime().newArgumentError("default_internal can not be nil"); } recv.getRuntime().setDefaultInternalEncoding(service.getEncodingFromObject(encoding)); return encoding; }
@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 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; }
@JRubyMethod(name = "end", compat = CompatVersion.RUBY1_9) public IRubyObject end19(ThreadContext context, IRubyObject index) { int i = backrefNumber(index); Ruby runtime = context.getRuntime(); int e = endCommon(runtime, i); if (e < 0) return runtime.getNil(); if (!str.singleByteOptimizable()) { updateCharOffset(); e = charOffsets.end[i]; } return RubyFixnum.newFixnum(runtime, e); }
@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(); }
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; }
public static RubyClass createTimeClass(Ruby runtime) { RubyClass timeClass = runtime.defineClass("Time", runtime.getObject(), TIME_ALLOCATOR); timeClass.index = ClassIndex.TIME; timeClass.setReifiedClass(RubyTime.class); runtime.setTime(timeClass); timeClass.includeModule(runtime.getComparable()); timeClass.defineAnnotatedMethods(RubyTime.class); return timeClass; }
@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(); }
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; }
// FIXME: We should have a better way of using the proper method based // on version as a general solution... private RubyString makeShared(Ruby runtime, RubyString str, int begin, int length) { if (runtime.is1_9()) { return str.makeShared19(runtime, begin, length); } else { return str.makeShared(runtime, begin, length); } }
@SuppressWarnings("unchecked") @JRubyMethod(name = "aliases", meta = true) public static IRubyObject aliases(ThreadContext context, IRubyObject recv) { Ruby runtime = context.runtime; EncodingService service = runtime.getEncodingService(); IRubyObject list[] = service.getEncodingList(); HashEntryIterator i = service.getAliases().entryIterator(); RubyHash result = RubyHash.newHash(runtime); while (i.hasNext()) { CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry> e = ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>) i.next()); IRubyObject alias = RubyString.newUsAsciiStringShared(runtime, e.bytes, e.p, e.end - e.p).freeze(context); IRubyObject name = RubyString.newUsAsciiStringShared(runtime, ((RubyEncoding) list[e.value.getIndex()]).name) .freeze(context); result.fastASet(alias, name); } result.fastASet( runtime.newString(EXTERNAL), runtime.newString(new ByteList(runtime.getDefaultExternalEncoding().getName()))); result.fastASet( runtime.newString(LOCALE), runtime.newString(new ByteList(service.getLocaleEncoding().getName()))); return result; }
/** * 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); } }
public static RubyClass createEncodingClass(Ruby runtime) { RubyClass encodingc = runtime.defineClass( "Encoding", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR); runtime.setEncoding(encodingc); encodingc.index = ClassIndex.ENCODING; encodingc.setReifiedClass(RubyEncoding.class); encodingc.kindOf = new RubyModule.KindOf() { @Override public boolean isKindOf(IRubyObject obj, RubyModule type) { return obj instanceof RubyEncoding; } }; encodingc.getSingletonClass().undefineMethod("allocate"); encodingc.defineAnnotatedMethods(RubyEncoding.class); return encodingc; }
@JRubyMethod(compat = CompatVersion.RUBY1_8) public IRubyObject select(ThreadContext context, Block block) { Ruby runtime = context.getRuntime(); final RubyArray result; if (regs == null) { if (begin < 0) return runtime.newEmptyArray(); IRubyObject s = str.substr(runtime, begin, end - begin); s.setTaint(isTaint()); result = block.yield(context, s).isTrue() ? runtime.newArray(s) : runtime.newEmptyArray(); } else { result = runtime.newArray(); boolean taint = isTaint(); for (int i = 0; i < regs.numRegs; i++) { IRubyObject s = str.substr(runtime, regs.beg[i], regs.end[i] - regs.beg[i]); if (taint) s.setTaint(true); if (block.yield(context, s).isTrue()) result.append(s); } } return result; }
protected static RubyTime s_mload(IRubyObject recv, RubyTime time, IRubyObject from) { Ruby runtime = recv.getRuntime(); DateTime dt = new DateTime(DateTimeZone.UTC); byte[] fromAsBytes = null; fromAsBytes = from.convertToString().getBytes(); if (fromAsBytes.length != 8) { throw runtime.newTypeError("marshaled time format differ"); } int p = 0; int s = 0; for (int i = 0; i < 4; i++) { p |= ((int) fromAsBytes[i] & 0xFF) << (8 * i); } for (int i = 4; i < 8; i++) { s |= ((int) fromAsBytes[i] & 0xFF) << (8 * (i - 4)); } boolean utc = false; if ((p & (1 << 31)) == 0) { dt = dt.withMillis(p * 1000L); time.setUSec((s & 0xFFFFF) % 1000); } else { p &= ~(1 << 31); utc = ((p >>> 30 & 0x1) == 0x1); dt = dt.withYear(((p >>> 14) & 0xFFFF) + 1900); dt = dt.withMonthOfYear(((p >>> 10) & 0xF) + 1); dt = dt.withDayOfMonth(((p >>> 5) & 0x1F)); dt = dt.withHourOfDay((p & 0x1F)); dt = dt.withMinuteOfHour(((s >>> 26) & 0x3F)); dt = dt.withSecondOfMinute(((s >>> 20) & 0x3F)); // marsaling dumps usec, not msec dt = dt.withMillisOfSecond((s & 0xFFFFF) / 1000); time.setUSec((s & 0xFFFFF) % 1000); } time.setDateTime(dt); if (!utc) time.localtime(); from.getInstanceVariables().copyInstanceVariablesInto(time); return time; }
public static RubyClass createMatchDataClass(Ruby runtime) { RubyClass matchDataClass = runtime.defineClass("MatchData", runtime.getObject(), MATCH_DATA_ALLOCATOR); runtime.setMatchData(matchDataClass); matchDataClass.index = ClassIndex.MATCHDATA; matchDataClass.setReifiedClass(RubyMatchData.class); runtime.defineGlobalConstant("MatchingData", matchDataClass); matchDataClass.kindOf = new RubyModule.KindOf() { @Override public boolean isKindOf(IRubyObject obj, RubyModule type) { return obj instanceof RubyMatchData; } }; matchDataClass.getMetaClass().undefineMethod("new"); matchDataClass.defineAnnotatedMethods(RubyMatchData.class); return matchDataClass; }
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"); } }
@JRubyMethod(name = "inspect") @Override public IRubyObject inspect() { if (str == null) return anyToString(); Ruby runtime = getRuntime(); RubyString result = runtime.newString(); result.cat((byte) '#').cat((byte) '<'); result.append(getMetaClass().getRealClass().to_s()); NameEntry[] names = new NameEntry[regs == null ? 1 : regs.numRegs]; if (pattern.numberOfNames() > 0) { for (Iterator<NameEntry> i = pattern.namedBackrefIterator(); i.hasNext(); ) { NameEntry e = i.next(); for (int num : e.getBackRefs()) names[num] = e; } } for (int i = 0; i < names.length; i++) { result.cat((byte) ' '); if (i > 0) { NameEntry e = names[i]; if (e != null) { result.cat(e.name, e.nameP, e.nameEnd - e.nameP); } else { result.cat((byte) ('0' + i)); } result.cat((byte) ':'); } IRubyObject v = RubyRegexp.nth_match(i, this); if (v.isNil()) { result.cat("nil".getBytes()); } else { result.append(((RubyString) v).inspectCommon(runtime.is1_9())); } } return result.cat((byte) '>'); }