Skip to content

Commit

Permalink
Showing 40 changed files with 266 additions and 297 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -124,5 +124,5 @@ services:
addons:
apt:
packages:
- oracle-java9-installer
# - oracle-java9-installer
- haveged
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
@@ -1247,7 +1247,7 @@ private RubyString inspectObj(final Ruby runtime, RubyString part) {

@JRubyMethod(name = "!")
public IRubyObject op_not(ThreadContext context) {
return context.runtime.newBoolean(!this.isTrue());
return isTrue() ? context.fals : context.tru;
}

/**
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/RubyDir.java
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ private static String globOptions(ThreadContext context, IRubyObject[] args, int
} else {
String[] keys = flags != null ? new String[] {"base", "flags"} : new String[] {"base"};
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) tmp, keys);
String base = rets[0].isNil() ? "" : RubyFile.get_path(context, rets[0]).asJavaString();
String base = rets[0] == UNDEF ? "" : RubyFile.get_path(context, rets[0]).asJavaString();

// Deep down in glob things are unhappy if base is not absolute.
if (!base.isEmpty()) {
@@ -212,7 +212,7 @@ private static String globOptions(ThreadContext context, IRubyObject[] args, int
base = new JRubyFile(runtime.getCurrentDirectory(), base).getAbsolutePath();
}
}
if (flags != null) flags[0] = rets[1].isNil() ? 0 : RubyNumeric.num2int(rets[1]);
if (flags != null) flags[0] = rets[1] == UNDEF ? 0 : RubyNumeric.num2int(rets[1]);
return base;
}
}
48 changes: 32 additions & 16 deletions core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@
import org.jruby.anno.JRubyModule;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.common.RubyWarnings;
import org.jruby.exceptions.MainExitException;
import org.jruby.exceptions.RaiseException;
import org.jruby.internal.runtime.methods.DynamicMethod;
@@ -1207,48 +1208,63 @@ private static RaiseException uncaughtThrow(Ruby runtime, IRubyObject tag, IRuby
}

@JRubyMethod(module = true, visibility = PRIVATE)
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject message) {
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject _message) {
final Ruby runtime = context.runtime;

if (runtime.warningsEnabled()) RubyIO.puts1(context, runtime.getGlobalVariables().get("$stderr"), message);
if (_message instanceof RubyArray) {
RubyArray messageArray = _message.convertToArray();
for (int i = 0; i < messageArray.size(); i++) warn(context, recv, messageArray.eltOk(i));
return context.nil;
}

return context.nil;
RubyString message = _message.convertToString();
if (!message.endsWithAsciiChar('\n')) {
message = (RubyString) message.op_plus19(context, runtime.newString("\n"));
}

return sites(context).warn.call(context, recv, runtime.getWarning(), message);
}

public static final String[] WARN_VALID_KEYS = {"uplevel"};

@JRubyMethod(module = true, rest = true, visibility = PRIVATE)
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
Ruby runtime = context.runtime;

boolean kwargs = false;
int uplevel = -1;
if (args.length > 1) {
IRubyObject tmp = TypeConverter.checkHashType(context.runtime, args[args.length - 1]);
if (!tmp.isNil()) {
kwargs = true;
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) tmp, "uplevel");
uplevel = RubyNumeric.num2int(rets[0]);
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) tmp, WARN_VALID_KEYS);
uplevel = rets[0] == UNDEF ? 0 : RubyNumeric.num2int(rets[0]);
}
}

RubyString message = context.runtime.newString();
// FIXME: This is not particularly efficient.
int numberOfMessages = kwargs ? args.length - 1 : args.length;
IRubyObject newline = runtime.newString("\n");

if (uplevel >= 0) {
if (kwargs) {
RubyStackTraceElement[] elements = context.runtime.getInstanceConfig().getTraceType().getBacktrace(context).getBacktrace(context.runtime);

// User can ask for level higher than stack
if (elements.length <= uplevel + 1) uplevel = 0;
if (elements.length <= uplevel + 1) uplevel = -1;

int index = uplevel + 1;
message.catString(elements[index].getFileName() + ":" + (elements[index].getLineNumber()) + " warning: ");
}

for (int i = 0; i < numberOfMessages; i++) {
message.append(args[i]);
if (i + 1 < numberOfMessages) message.cat('\n');
RubyString baseMessage = context.runtime.newString();
baseMessage.catString(elements[index].getFileName() + ":" + (elements[index].getLineNumber()) + " warning: ");

for (int i = 0; i < numberOfMessages; i++) {
warn(context, recv, baseMessage.op_plus19(context, args[i]));
}
} else {
for (int i = 0; i < numberOfMessages; i++) {
warn(context, recv, args[i].convertToString());
}
}

if (message.size() > 0) warn(context, recv, message);

return context.nil;
}

2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyMatchData.java
Original file line number Diff line number Diff line change
@@ -377,7 +377,7 @@ public IRubyObject[] getNamedBackrefValues(Ruby runtime) {

@JRubyMethod
@Override
public IRubyObject inspect() {
public RubyString inspect() {
if (str == null) return anyToString();

Ruby runtime = getRuntime();
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -2297,7 +2297,7 @@ public RubyFixnum hash() {
*/
@JRubyMethod(name = "to_s", alias = "inspect")
@Override
public IRubyObject to_s() {
public RubyString to_s() {
if(isSingleton()){
IRubyObject attached = ((MetaClass) this).getAttached();
RubyString buffer = getRuntime().newString("#<Class:");
10 changes: 7 additions & 3 deletions core/src/main/java/org/jruby/RubyNumeric.java
Original file line number Diff line number Diff line change
@@ -644,13 +644,17 @@ public RubyNumeric asNumeric() {
* ================
*/

@JRubyMethod(name = "!")
public IRubyObject op_not(ThreadContext context) {
return context.fals;
}

/** num_sadded
*
*/
@JRubyMethod(name = "singleton_method_added")
public static IRubyObject sadded(IRubyObject self, IRubyObject name) {
Ruby runtime = self.getRuntime();
throw runtime.newTypeError(str(runtime,
public static IRubyObject singleton_method_added(ThreadContext context, IRubyObject self, IRubyObject name) {
throw context.runtime.newTypeError(str(runtime,
"can't define singleton method \"", ids(runtime, name), "\" for ", types(runtime, self.getType())));
}

4 changes: 1 addition & 3 deletions core/src/main/java/org/jruby/RubyProc.java
Original file line number Diff line number Diff line change
@@ -81,10 +81,8 @@ protected RubyProc(Ruby runtime, RubyClass rubyClass, Block.Type type, String fi


public RubyProc(Ruby runtime, RubyClass rubyClass, Block block, String file, int line) {
this(runtime, rubyClass, block.type);
this(runtime, rubyClass, block.type, file, line);
this.block = block;
this.file = file;
this.line = line;
}

public static RubyClass createProcClass(Ruby runtime) {
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/RubyRational.java
Original file line number Diff line number Diff line change
@@ -1272,9 +1272,9 @@ public RubyString inspect(ThreadContext context) {
private RubyString inspectImpl(Ruby runtime) {
RubyString str = RubyString.newString(runtime, new ByteList(12), USASCIIEncoding.INSTANCE);
str.cat((byte)'(');
str.append(num.inspect());
str.append((RubyString) num.inspect());
str.cat((byte)'/');
str.append(den.inspect());
str.append((RubyString) den.inspect());
str.cat((byte)')');
return str;
}
15 changes: 14 additions & 1 deletion core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
@@ -2343,7 +2343,7 @@ private void raiseIndexOutOfString(int index) {
*/
@Override
@JRubyMethod(name = "inspect")
public IRubyObject inspect() {
public RubyString inspect() {
return inspect(getRuntime());
}

@@ -2584,6 +2584,12 @@ public RubyString append(IRubyObject other) {
return cat(otherStr.value);
}

public RubyString append(RubyString otherStr) {
modifyCheck();
infectBy(otherStr);
return cat(otherStr.value);
}

public RubyString append19(IRubyObject other) {
modifyCheck();

@@ -4424,6 +4430,13 @@ private boolean end_with_pCommon(IRubyObject tmp) {
return false;
}

public boolean endsWithAsciiChar(char c) {
ByteList value = this.value;
int size;

return value.getEncoding().isAsciiCompatible() && (size = value.realSize()) > 0 && value.get(size - 1) == c;
}

private static final ByteList SPACE_BYTELIST = RubyInteger.singleCharByteList((byte) ' ');

private IRubyObject justify(Ruby runtime, IRubyObject arg0, int jflag) {
37 changes: 26 additions & 11 deletions core/src/main/java/org/jruby/RubyStruct.java
Original file line number Diff line number Diff line change
@@ -33,6 +33,8 @@

package org.jruby;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jruby.anno.JRubyClass;
@@ -355,21 +357,34 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {

IRubyObject keywordInit = RubyStruct.getInternalVariable(classOf(), "__keyword_init__");

Ruby runtime = context.runtime;
IRubyObject nil = context.nil;

if (keywordInit.isTrue()) {
if (args.length != 1 || !(args[0] instanceof RubyHash)) throw context.runtime.newArgumentError("wrong number of arguments (given " + args.length + ", expected 0)");
RubyHash kwArgs = args[0].convertToHash();
IRubyObject maybeKwargs = ArgsUtil.getOptionsArg(runtime, args);

if (maybeKwargs.isNil())
throw runtime.newArgumentError("wrong number of arguments (given " + args.length + ", expected 0)");

RubyHash kwArgs = (RubyHash) maybeKwargs;
RubyArray __members__ = __member__();
String[] members = Stream.of(__members__.toJavaArray())
.map(o -> RubySymbol.objectToSymbolString(o))
.collect(Collectors.toList())
.toArray(new String[__members__.size()]);
args = ArgsUtil.extractKeywordArgs(context, kwArgs, members);
Set<Map.Entry<IRubyObject, IRubyObject>> entries = kwArgs.directEntrySet();

entries.stream().forEach(
entry -> {
IRubyObject key = entry.getKey();
if (!(key instanceof RubySymbol))
key = runtime.newSymbol(key.convertToString().getByteList());
IRubyObject index = __members__.index(context, key);
if (index.isNil()) throw runtime.newArgumentError("unknown keywords: " + key);
values[index.convertToInteger().getIntValue()] = entry.getValue();
});
} else {
System.arraycopy(args, 0, values, 0, args.length);
Helpers.fillNil(values, args.length, values.length, runtime);
}

System.arraycopy(args, 0, values, 0, args.length);
Helpers.fillNil(values, args.length, values.length, context.runtime);

return context.nil;
return nil;
}

@JRubyMethod(visibility = PRIVATE)
14 changes: 1 addition & 13 deletions core/src/main/java/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
@@ -650,20 +650,8 @@ private static void initThreadName(final Ruby runtime, final Thread thread, fina
thread.setName(newName);
}

// TODO likely makes sense to have a counter or the Ruby class directly (could be included with JMX)
private static final WeakHashMap<Ruby, AtomicLong> threadCount = new WeakHashMap<Ruby, AtomicLong>(4);

private static long incAndGetThreadCount(final Ruby runtime) {
AtomicLong counter = threadCount.get(runtime);
if ( counter == null ) {
synchronized (runtime) {
counter = threadCount.get(runtime);
if ( counter == null ) {
threadCount.put(runtime, counter = new AtomicLong(0));
}
}
}
return counter.incrementAndGet();
return runtime.getThreadService().incrementAndGetThreadCount();
}

private static RubyThread startThread(final IRubyObject recv, final IRubyObject[] args, boolean callInit, Block block) {
3 changes: 3 additions & 0 deletions core/src/main/java/org/jruby/common/RubyWarnings.java
Original file line number Diff line number Diff line change
@@ -207,6 +207,9 @@ public void warning(ID id, String fileName, int lineNumber, String message) {
@JRubyMethod
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject arg) {
Ruby runtime = context.runtime;

if (!runtime.warningsEnabled()) return context.nil;

TypeConverter.checkType(context, arg, runtime.getString());
RubyString str = (RubyString) arg;
if (!str.getEncoding().isAsciiCompatible()) {
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/exceptions/FrozenError.java
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@
*
* @see RubyFrozenError
*/
public class FrozenError extends StandardError {
public class FrozenError extends RuntimeError {
public FrozenError(String message, RubyFrozenError exception) {
super(message, exception);
}
8 changes: 7 additions & 1 deletion core/src/main/java/org/jruby/ext/date/DateUtils.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jruby.ext.date;

import org.jruby.*;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

@@ -230,7 +231,8 @@ static int offset_to_sec(ThreadContext context, IRubyObject of) {
//if (d != n) rb_warning("fraction of offset is ignored");
return (int) n;
case STRING:
vs = date_zone_to_diff(context, (RubyString) of);
RubyClass date = getDate(context.runtime);
vs = sites(context).zone_to_diff.call(context, date, date, of);

if (!(vs instanceof RubyFixnum)) return INVALID_OFFSET;
n = ((RubyFixnum) vs).getLongValue();
@@ -439,6 +441,10 @@ else if (iy > REFORM_END_YEAR)
return style;
}

private static JavaSites.DateSites sites(ThreadContext context) {
return context.sites.Date;
}

private static final int JC_PERIOD0 = 1461; /* 365.25 * 4 */
private static final int GC_PERIOD0 = 146097; /* 365.2425 * 400 */
private static final int CM_PERIOD0 = 71149239; /* (lcm 7 1461 146097) */
11 changes: 2 additions & 9 deletions core/src/main/java/org/jruby/ext/date/RubyDate.java
Original file line number Diff line number Diff line change
@@ -234,7 +234,7 @@ private void initialize(final ThreadContext context, IRubyObject arg, IRubyObjec

static final int DAY_IN_SECONDS = 86_400; // 24 * 60 * 60
static final int DAY_MS = 86_400_000; // 24 * 60 * 60 * 1000
private static RubyFixnum DAY_MS_CACHE;
private RubyFixnum DAY_MS_CACHE;

private long initMillis(final ThreadContext context, IRubyObject ajd) {
final Ruby runtime = context.runtime;
@@ -272,7 +272,7 @@ private long initMillis(final ThreadContext context, IRubyObject ajd) {
return ((RubyFixnum) millis).getLongValue();
}

private static RubyFixnum DAY_MS(final ThreadContext context) {
private RubyFixnum DAY_MS(final ThreadContext context) {
RubyFixnum v = DAY_MS_CACHE;
if (v == null) v = DAY_MS_CACHE = context.runtime.newFixnum(DAY_MS);
return v;
@@ -1394,13 +1394,6 @@ static RubyRational newRationalConvert(ThreadContext context, IRubyObject num, l
return (RubyRational) RubyRational.newRationalConvert(context, num, context.runtime.newFixnum(den));
}

private static final CachingCallSite zone_to_diff = new FunctionalCachingCallSite("zone_to_diff");

static IRubyObject date_zone_to_diff(final ThreadContext context, RubyString str) {
final RubyClass klass = getDate(context.runtime);
return zone_to_diff.call(context, klass, klass, str);
}

// def jd_to_ajd(jd, fr, of=0) jd + fr - of - Rational(1, 2) end
private static double jd_to_ajd(long jd) { return jd - 0.5; }

21 changes: 21 additions & 0 deletions core/src/main/java/org/jruby/ext/jruby/JRubyUtilLibrary.java
Original file line number Diff line number Diff line change
@@ -110,6 +110,11 @@ public static IRubyObject unseeded_hash(ThreadContext context, IRubyObject recv)
}
}

/**
* Provide stats on how many method and constant invalidations have occurred globally.
*
* This was added for Pry in https://github.com/jruby/jruby/issues/4384
*/
@JRubyMethod(name = "cache_stats", module = true)
public static IRubyObject cache_stats(ThreadContext context, IRubyObject self) {
Ruby runtime = context.runtime;
@@ -120,4 +125,20 @@ public static IRubyObject cache_stats(ThreadContext context, IRubyObject self) {

return stat;
}

/**
* Return a list of files and extensions that JRuby treats as internal (or "built-in"), skipping load path and
* filesystem search.
*
* This was added for Bootsnap in https://github.com/Shopify/bootsnap/issues/162
*/
@JRubyMethod(module = true)
public static RubyArray internal_libraries(ThreadContext context, IRubyObject self) {
Ruby runtime = context.runtime;
List<String> builtinLibraries = runtime.getLoadService().getBuiltinLibraries();

IRubyObject[] names = builtinLibraries.stream().map(name -> runtime.newString(name)).toArray(i->new IRubyObject[i]);

return runtime.newArrayNoCopy(names);
}
}
20 changes: 11 additions & 9 deletions core/src/main/java/org/jruby/ext/strscan/RubyStringScanner.java
Original file line number Diff line number Diff line change
@@ -605,24 +605,26 @@ private IRubyObject inspect(String msg) {

private static final int INSPECT_LENGTH = 5;

private static final byte[] DOT_BYTES = "...".getBytes();

private IRubyObject inspect1() {
if (pos == 0) return RubyString.newEmptyString(getRuntime());
final Ruby runtime = getRuntime();
if (pos == 0) return RubyString.newEmptyString(runtime);
if (pos > INSPECT_LENGTH) {
return RubyString.newStringNoCopy(getRuntime(), "...".getBytes()).
append(str.substr(getRuntime(), pos - INSPECT_LENGTH, INSPECT_LENGTH)).inspect();
} else {
return str.substr(getRuntime(), 0, pos).inspect();
return RubyString.newStringNoCopy(runtime, DOT_BYTES).
append(str.substr(runtime, pos - INSPECT_LENGTH, INSPECT_LENGTH)).inspect();
}
return str.substr(runtime, 0, pos).inspect();
}

private IRubyObject inspect2() {
if (pos >= str.getByteList().getRealSize()) return RubyString.newEmptyString(getRuntime());
final Ruby runtime = getRuntime();
if (pos >= str.getByteList().getRealSize()) return RubyString.newEmptyString(runtime);
int len = str.getByteList().getRealSize() - pos;
if (len > INSPECT_LENGTH) {
return ((RubyString)str.substr(getRuntime(), pos, INSPECT_LENGTH)).cat("...".getBytes()).inspect();
} else {
return str.substr(getRuntime(), pos, len).inspect();
return ((RubyString) str.substr(runtime, pos, INSPECT_LENGTH)).cat(DOT_BYTES).inspect();
}
return str.substr(runtime, pos, len).inspect();
}

@JRubyMethod(name = "must_C_version", meta = true)
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
package org.jruby.internal.runtime;

import java.lang.ref.SoftReference;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;

import java.util.ArrayList;
@@ -139,6 +140,8 @@ public class ThreadService {

private final ReentrantLock criticalLock = new ReentrantLock();

private final AtomicLong threadCount = new AtomicLong(0);

public ThreadService(final Ruby runtime) {
this.runtime = runtime;
this.localContext = new ThreadLocal<SoftReference<ThreadContext>>();
@@ -293,6 +296,10 @@ public boolean getCritical() {
return criticalLock.isHeldByCurrentThread();
}

public long incrementAndGetThreadCount() {
return threadCount.incrementAndGet();
}

@Deprecated
public Map<Object, RubyThread> getRubyThreadMap() {
return rubyThreadMap;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jruby.javasupport.binding;

import com.headius.modulator.Modulator;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
@@ -539,6 +540,9 @@ private static int addNewMethods(
// Skip private methods, since they may mess with dispatch
if ( Modifier.isPrivate(mod) ) continue;

// Skip protected methods if we can't set accessible
if ( !Modifier.isPublic(mod) && !Modulator.trySetAccessible(method)) continue;

// ignore bridge methods because we'd rather directly call methods that this method
// is bridging (and such methods are by definition always available.)
if ( ( mod & ACC_BRIDGE ) != 0 ) continue;
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java
Original file line number Diff line number Diff line change
@@ -879,7 +879,7 @@ private int yylex() throws IOException {
continue;
case '#': { /* it's a comment */
this.tokenSeen = tokenSeen;
if (!tokenSeen || !warnings.isVerbose()) {
if (!tokenSeen || warnings.isVerbose()) {
if (!parser_magic_comment(lexb.makeShared(lex_p, lex_pend - lex_p))) {
if (comment_at_top()) set_file_encoding(lex_p, lex_pend);
}
6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/runtime/JavaSites.java
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@ public class JavaSites {
public final TracePointSites TracePoint = new TracePointSites();
public final MarshalSites Marshal = new MarshalSites();
public final PathnameSites Pathname = new PathnameSites();
public final DateSites Date = new DateSites();

public static class BasicObjectSites {
public final CallSite respond_to = new FunctionalCachingCallSite("respond_to?");
@@ -88,6 +89,7 @@ public static class KernelSites {
public final CheckedSites to_hash_checked = new CheckedSites("to_hash");
public final CallSite write = new FunctionalCachingCallSite("write");
public final CallSite call = new FunctionalCachingCallSite("call");
public final CallSite warn = new FunctionalCachingCallSite("warn");
}

public static class ArraySites {
@@ -453,6 +455,10 @@ public static class PathnameSites {
public final CallSite op_plus = new FunctionalCachingCallSite("+");
}

public static class DateSites {
public final CallSite zone_to_diff = new FunctionalCachingCallSite("zone_to_diff");
}

public static class CheckedSites {
public final RespondToCallSite respond_to_X;
public final CachingCallSite respond_to_missing = new FunctionalCachingCallSite("respond_to_missing?");
Original file line number Diff line number Diff line change
@@ -167,6 +167,15 @@ private FoundLibrary findFileResourceWithLoadPath(String searchName, String suff
DebugLog.Resource.logTry(pathWithSuffix);
FileResource resource = JRubyFile.createResourceAsFile(runtime, pathWithSuffix);
if (resource.exists()) {
if (resource.absolutePath() != resource.canonicalPath()) {
FileResource expandedResource = JRubyFile.createResourceAsFile(runtime, resource.canonicalPath());
if (expandedResource.exists()){
resource = expandedResource;
String scriptName = resolveScriptName(resource, resource.canonicalPath());
String loadName = resolveLoadName(resource, searchName + suffix);
return new FoundLibrary(ResourceLibrary.create(searchName, scriptName, resource), loadName);
}
}
DebugLog.Resource.logFound(pathWithSuffix);
String scriptName = resolveScriptName(resource, pathWithSuffix);
String loadName = resolveLoadName(resource, searchName + suffix);
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/runtime/load/LoadService.java
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipException;

import org.jruby.Ruby;
@@ -628,6 +629,13 @@ public void removeBuiltinLibrary(String name) {
builtinLibraries.remove(name);
}

/**
* Get a list of all libraries JRuby considers "built-in".
*/
public List<String> getBuiltinLibraries() {
return builtinLibraries.keySet().stream().collect(Collectors.toList());
}

public void removeInternalLoadedFeature(String name) {
loadedFeatures.deleteString(runtime.getCurrentContext(), name);
}
8 changes: 3 additions & 5 deletions core/src/main/java/org/jruby/util/IOInputStream.java
Original file line number Diff line number Diff line change
@@ -50,13 +50,11 @@
* that it responds to read() like IO.
*/
public class IOInputStream extends InputStream {

private static final CallSite readAdapter = MethodIndex.getFunctionalCallSite("read");
private static final CallSite closeAdapter = MethodIndex.getFunctionalCallSite("close");

private final IRubyObject io;
private final InputStream in;
private final RubyFixnum numOne;
private final IRubyObject numOne;
private final CallSite readAdapter = MethodIndex.getFunctionalCallSite("read");
private final CallSite closeAdapter = MethodIndex.getFunctionalCallSite("close");

/**
* Creates a new InputStream with the object provided.
4 changes: 1 addition & 3 deletions core/src/main/java/org/jruby/util/IOOutputStream.java
Original file line number Diff line number Diff line change
@@ -51,12 +51,10 @@
* @author <a href="mailto:Ola.Bini@ki.se">Ola Bini</a>
*/
public class IOOutputStream extends OutputStream {

private static final CallSite closeAdapter = MethodIndex.getFunctionalCallSite("close");

private final IRubyObject io;
private final OutputStream out;
private final CallSite writeAdapter;
private final CallSite closeAdapter = MethodIndex.getFunctionalCallSite("close");
private final Encoding encoding;

/**
25 changes: 12 additions & 13 deletions core/src/main/java/org/jruby/util/KCode.java
Original file line number Diff line number Diff line change
@@ -29,23 +29,25 @@
package org.jruby.util;

import org.jcodings.Encoding;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.EUCJPEncoding;
import org.jcodings.specific.SJISEncoding;
import org.jcodings.specific.UTF8Encoding;

public enum KCode {
NIL(null, "ASCII", 0),
NONE("NONE", "ASCII", 0),
UTF8("UTF8", "UTF8", 64),
SJIS("SJIS", "SJIS", 48),
EUC("EUC", "EUCJP", 32);
NIL(null, ASCIIEncoding.INSTANCE, 0),
NONE("NONE", ASCIIEncoding.INSTANCE, 0),
UTF8("UTF8", UTF8Encoding.INSTANCE, 64),
SJIS("SJIS", SJISEncoding.INSTANCE, 48),
EUC("EUC", EUCJPEncoding.INSTANCE, 32);

private final String kcode;
private final String encodingName;
private final Encoding encoding;
private final int code;

private volatile Encoding encoding;

private KCode(String kcode, String encodingName, int code) {
private KCode(String kcode, Encoding encoding, int code) {
this.kcode = kcode;
this.encodingName = encodingName;
this.encoding = encoding;
this.code = code;
}

@@ -89,9 +91,6 @@ public static KCode fromBits(int bits) {
}

public Encoding getEncoding() {
if (encoding == null) {
encoding = Encoding.load(encodingName);
}
return encoding;
}

12 changes: 12 additions & 0 deletions spec/java_integration/methods/dispatch_spec.rb
Original file line number Diff line number Diff line change
@@ -293,3 +293,15 @@
end.not_to raise_error
end
end

if TestHelper::JAVA_9
describe "An overridden Java method" do
describe "with a non-public base implementation" do
it "is called using a public override" do
expect do
java.util.Properties.new.clone
end.not_to raise_error
end
end
end
end

This file was deleted.

1 change: 1 addition & 0 deletions spec/tags/ruby/core/module/refine_tags.txt
Original file line number Diff line number Diff line change
@@ -7,3 +7,4 @@ fails:Module#refine module inclusion activates all refinements from all ancestor
fails:Module#refine for methods accessed indirectly is honored by Kernel#send
fails:Module#refine for methods accessed indirectly is honored by BasicObject#__send__
fails:Module#refine for methods accessed indirectly is honored by Symbol#to_proc
fails:Module#refine for methods accessed indirectly is honored by string interpolation
1 change: 1 addition & 0 deletions spec/tags/ruby/core/proc/source_location_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Proc#source_location returns the first line of a multi-line proc (i.e. the line containing 'proc do')
7 changes: 4 additions & 3 deletions test/jruby.index
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ jruby/test_digest_extend
jruby/test_digest2
jruby/test_env
jruby/test_etc
jruby/test_exception
jruby/test_file
# IRBuilder is unable to build these currently
#jruby/test_flip
@@ -53,7 +54,6 @@ jruby/test_marshal_with_instance_variables
jruby/test_marshal_gemspec
jruby/test_method_missing
jruby/test_name_error
jruby/test_no_stack_trace_stomp
jruby/test_pack
jruby/test_primitive_to_java
jruby/test_process
@@ -74,13 +74,14 @@ jruby/test_system
jruby/test_system_error
jruby/test_timeout
jruby/test_thread
# FIXME probably should figure this one out
#test_thread_backtrace
jruby/test_thread_backtrace
jruby/test_threaded_nonlocal_return
jruby/test_time
jruby/test_unmarshal
jruby/test_vietnamese_charset
jruby/test_win32
# TODO test_yaml seems outdated
# jruby/test_yaml
jruby/test_zlib

# these tests are last because they pull in libraries that can affect others
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
require 'test/unit'

class TestNoStackTraceStomp < Test::Unit::TestCase
def raise_an_error
raise "an error"
class TestException < Test::Unit::TestCase

def raise_an_error
raise "an error"
end

def rescue_an_error
@@ -20,4 +21,5 @@ def test_good_stack_trace
assert_match(/`raise_an_error'/, e.backtrace[0])
end
end

end
1 change: 1 addition & 0 deletions test/jruby/test_helper.rb
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ module TestHelper
IBM_JVM = RbConfig::CONFIG['host_vendor'] =~ /IBM Corporation/

JAVA_8 = ENV_JAVA['java.specification.version'] >= '1.8'
JAVA_9 = ENV_JAVA['java.specification.version'] > '1.8'

def q
WINDOWS ? '"' : '\''
9 changes: 9 additions & 0 deletions test/jruby/test_jruby_core_ext.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'test/unit'
require 'jruby/util'

class TestJRubyCoreExt < Test::Unit::TestCase

@@ -76,6 +77,14 @@ def test_with_current_runtime_as_global
assert_equal other_runtime, org.jruby.Ruby.global_runtime
end

def test_internal_libraries
internal_libraries = JRuby::Util.internal_libraries

assert_equal Array, internal_libraries.class
assert_true internal_libraries.size > 0
assert_include internal_libraries, "cgi/escape.jar"
end

private

def assert_same_contents(expect, actual)
13 changes: 0 additions & 13 deletions test/jruby/test_mathn_1_9.rb

This file was deleted.

14 changes: 4 additions & 10 deletions test/jruby/test_thread_backtrace.rb
Original file line number Diff line number Diff line change
@@ -10,20 +10,14 @@ def test_simple_backtrace
end
end.value

# These traces were modified during the new mixed-mode backtrace work
# to match the RubyProc calls at the top of a new Thread's stack.
if $0 == __FILE__
expected = [
/test\/test_thread_backtrace\.rb:7:in `test_simple_backtrace'/,
/org\/jruby\/RubyProc\.java:[0-9]+:in `call'/,
/org\/jruby\/RubyProc\.java:[0-9]+:in `call'/]
expected = [ /test\/jruby\/test_thread_backtrace\.rb:7:in `block in test_simple_backtrace'/ ]
else
expected = [
/\/test\/test_thread_backtrace\.rb:7:in `test_simple_backtrace'/,
/org\/jruby\/RubyProc\.java:[0-9]+:in `call'/,
/org\/jruby\/RubyProc\.java:[0-9]+:in `call'/]
expected = [ /test\/jruby\/test_thread_backtrace\.rb:7:in `block in test_simple_backtrace'/ ]
end

puts " " + backtrace.join("\n ") if $VERBOSE

expected.each_with_index do |pattern, index|
assert pattern =~ backtrace[index],
"mismatched traces: #{backtrace[index].inspect} did not match #{pattern.inspect}"
69 changes: 44 additions & 25 deletions test/jruby/test_yaml.rb
Original file line number Diff line number Diff line change
@@ -4,14 +4,18 @@
# $Id: test_yaml.rb 16084 2008-04-19 11:45:39Z knu $
#
require 'test/unit'
require 'yaml'

# [ruby-core:01946]
module YAML_Tests
StructTest = Struct::new(:c)
end

class YAML_Unit_Tests < Test::Unit::TestCase

def setup
require 'yaml'
end

#
# Convert between YAML and the object to verify correct parsing and
# emitting
@@ -1676,17 +1680,17 @@ def test_JRUBY_2192
assert_equal FooXSmith, obj.class
end

class PersonTestOne
yaml_as 'tag:data.allman.ms,2008:Person'
end

def roundtrip(text)
assert_equal text, YAML.load(YAML.dump(text))
end

def test_JRUBY_2976
assert_equal "--- !data.allman.ms,2008/Person {}\n\n", PersonTestOne.new.to_yaml
assert_equal PersonTestOne, YAML.load(PersonTestOne.new.to_yaml).class
personTestOne = Class.new do
yaml_as 'tag:data.allman.ms,2008:Person'
end

assert_equal "--- !data.allman.ms,2008/Person {}\n\n", personTestOne.new.to_yaml
assert_equal personTestOne, YAML.load(personTestOne.new.to_yaml).class


Hash.class_eval do
@@ -1732,31 +1736,31 @@ def self.from_s (s)
end
end

#
# opening Badger to add custom YAML serialization
#
class ::Badger
yaml_as "tag:ruby.yaml.org,2002:#{self}"
def test_JRUBY_3773
#
# opening Badger to add custom YAML serialization
#
::Badger.class_eval do
yaml_as "tag:ruby.yaml.org,2002:#{self}"

def to_yaml (opts={})
YAML::quick_emit(self.object_id, opts) do |out|
out.map(taguri) do |map|
map.add("s", to_s)
def to_yaml (opts={})
YAML::quick_emit(self.object_id, opts) do |out|
out.map(taguri) do |map|
map.add("s", to_s)
end
end
end
end

def Badger.yaml_new (klass, tag, val)
s = val["s"]
begin
Badger.from_s s
rescue => e
raise "failed to decode Badger from '#{s}'"
def Badger.yaml_new (klass, tag, val)
s = val["s"]
begin
Badger.from_s s
rescue => e
raise "failed to decode Badger from '#{s}'"
end
end
end
end

def test_JRUBY_3773
b = Badger.new("Axel", 35)

assert_equal YAML::dump(b), <<OUT
@@ -1872,4 +1876,19 @@ def test_JRUBY_5581
assert_equal YAML.load("---\ndate: 2011-03-03 00:00:01.0210000000 Z").to_yaml, "--- \ndate: 2011-03-03 00:03:31 Z\n"
assert_equal YAML.load("---\ndate: 2011-03-03 00:00:01.0000000012 Z").to_yaml, "--- \ndate: 2011-03-03 00:00:01.000012 Z\n"
end

# JRUBY-5387
def test_argument_error_with_invalid_syntax
assert_raise(ArgumentError) do
YAML.load(<<EOY)
Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'railties'
s.version = version
s.summary = 'Tools for creating, working with, and running Rails applications.'
s.description = 'Rails internals: application bootup, plugins, generators, and rake tasks.'
EOY
end
end

end
19 changes: 0 additions & 19 deletions test/jruby/test_yaml_1_9.rb

This file was deleted.

92 changes: 0 additions & 92 deletions test/jruby/test_yamlstore.rb

This file was deleted.

0 comments on commit 00cecc9

Please sign in to comment.