Skip to content

Commit

Permalink
Merge JRuby 9.1.7.0 into truffle-head
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Jan 11, 2017
2 parents e22ed14 + 68056ae commit 87f774a
Show file tree
Hide file tree
Showing 39 changed files with 738 additions and 484 deletions.
2 changes: 1 addition & 1 deletion COPYING
@@ -1,4 +1,4 @@
JRuby is Copyright (c) 2007-2016 The JRuby project, and is released
JRuby is Copyright (c) 2007-2017 The JRuby project, and is released
under a tri EPL/GPL/LGPL license. You can use it, redistribute it
and/or modify it under the terms of the:

Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
9.1.7.0-SNAPSHOT
9.1.7.0
2 changes: 1 addition & 1 deletion core/pom.rb
Expand Up @@ -59,7 +59,7 @@

jar 'com.headius:invokebinder:1.7'
jar 'com.headius:options:1.4'
jar 'com.headius:unsafe-fences:1.0-SNAPSHOT'
jar 'com.headius:unsafe-fences:1.0'

jar 'bsf:bsf:2.4.0', :scope => 'provided'
jar 'com.jcraft:jzlib:1.1.3'
Expand Down
4 changes: 2 additions & 2 deletions core/pom.xml
Expand Up @@ -12,7 +12,7 @@ DO NOT MODIFIY - GENERATED CODE
<parent>
<groupId>org.jruby</groupId>
<artifactId>jruby-parent</artifactId>
<version>9.1.7.0-SNAPSHOT</version>
<version>9.1.7.0</version>
</parent>
<artifactId>jruby-core</artifactId>
<name>JRuby Core</name>
Expand Down Expand Up @@ -203,7 +203,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.headius</groupId>
<artifactId>unsafe-fences</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.0</version>
</dependency>
<dependency>
<groupId>bsf</groupId>
Expand Down
44 changes: 25 additions & 19 deletions core/src/main/java/org/jruby/Ruby.java
Expand Up @@ -2862,16 +2862,11 @@ public void loadFile(String scriptName, InputStream in, boolean wrap) {
ThreadContext.pushBacktrace(context, "(root)", file, 0);
context.preNodeEval(self);
ParseResult parseResult = parseFile(scriptName, in, null);
RootNode root = (RootNode) parseResult;

if (wrap) {
// toss an anonymous module into the search path
RubyModule wrapper = RubyModule.newModule(this);
((RubyBasicObject)self).extend(new IRubyObject[] {wrapper});
RootNode root = (RootNode) parseResult;
StaticScope top = root.getStaticScope();
StaticScope newTop = staticScopeFactory.newLocalScope(null);
top.setPreviousCRefScope(newTop);
top.setModule(wrapper);
wrapRootForLoad((RubyBasicObject) self, root);
}

runInterpreter(context, parseResult, self);
Expand Down Expand Up @@ -2903,24 +2898,39 @@ public void loadScope(IRScope scope, boolean wrap) {
}

public void compileAndLoadFile(String filename, InputStream in, boolean wrap) {
InputStream readStream = in;

// script was not found in cache above, so proceed to compile
RootNode scriptNode = (RootNode) parseFile(readStream, filename, null);

IRubyObject self = wrap ? getTopSelf().rbClone() : getTopSelf();
ThreadContext context = getCurrentContext();
InputStream readStream = in;

String oldFile = context.getFile();
int oldLine = context.getLine();
try {
context.setFileAndLine(scriptNode.getFile(), scriptNode.getLine());
context.preNodeEval(self);
ParseResult parseResult = parseFile(filename, in, null);
RootNode root = (RootNode) parseResult;

runNormally(scriptNode, wrap);
if (wrap) {
wrapRootForLoad((RubyBasicObject) self, root);
} else {
root.getStaticScope().setModule(getObject());
}

runNormally(root, wrap);
} finally {
context.setFileAndLine(oldFile, oldLine);
context.postNodeEval();
}
}

private void wrapRootForLoad(RubyBasicObject self, RootNode root) {
// toss an anonymous module into the search path
RubyModule wrapper = RubyModule.newModule(this);
self.extend(new IRubyObject[] {wrapper});
StaticScope top = root.getStaticScope();
StaticScope newTop = staticScopeFactory.newLocalScope(null);
top.setPreviousCRefScope(newTop);
top.setModule(wrapper);
}

public void loadScript(Script script) {
loadScript(script, false);
}
Expand Down Expand Up @@ -3167,10 +3177,6 @@ public void tearDown(boolean systemExit) {

final ThreadContext context = getCurrentContext();

// Disable event hooks during runtime teardown
// This avoids deadlocks if some other thread is holding a debugger lock while we're trying to exit
context.setEventHooksEnabled(false);

// FIXME: 73df3d230b9d92c7237d581c6366df1b92ad9b2b exposed no toplevel scope existing anymore (I think the
// bogus scope I removed was playing surrogate toplevel scope and wallpapering this bug). For now, add a
// bogus scope back for at_exit block run. This is buggy if at_exit is capturing vars.
Expand Down
45 changes: 23 additions & 22 deletions core/src/main/java/org/jruby/RubyArray.java
Expand Up @@ -71,6 +71,7 @@

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
Expand Down Expand Up @@ -3021,46 +3022,46 @@ protected boolean flatten(ThreadContext context, final int level, final RubyArra
// TODO: (CON) We can flatten packed versions efficiently if length does not change (e.g. [[1,2],[]])
unpack();
final Ruby runtime = context.runtime;
RubyArray stack = newArrayLight(runtime, ARRAY_DEFAULT_SIZE);
IdentityHashMap<Object, Object> memo = new IdentityHashMap<Object, Object>();
RubyArray ary = this;
memo.put(ary, NEVER);
boolean modified = false;

ArrayList<Object> stack = null;
IdentityHashMap<RubyArray, IRubyObject> memo = null; // used as an IdentityHashSet

RubyArray ary = this;
int i = 0;

try {
while (true) {
IRubyObject tmp;
while (i < ary.realLength) {
IRubyObject elt = ary.eltOk(i++);
if (level >= 0 && stack.size() / 2 >= level) {
if (level >= 0 && (stack == null ? 0 : stack.size()) / 2 >= level) {
result.append(elt);
continue;
}
tmp = TypeConverter.checkArrayType(elt);
if (tmp.isNil()) {
result.append(elt);
} else {
modified = true;
IRubyObject tmp = TypeConverter.checkArrayType(elt);
if (tmp.isNil()) result.append(elt);
else { // nested array element
if (memo == null) {
memo = new IdentityHashMap<>(4 + 1);
memo.put(this, NEVER);
}
if (memo.get(tmp) != null) throw runtime.newArgumentError("tried to flatten recursive array");
memo.put(tmp, NEVER);
stack.append(ary);
stack.append(RubyFixnum.newFixnum(runtime, i));
ary = (RubyArray)tmp;
if (stack == null) stack = new ArrayList<>(8); // fine hold 4-level deep nesting
stack.add(ary); stack.add(i); // add (ary, i) pair
ary = (RubyArray) tmp;
memo.put(ary, NEVER);
i = 0;
}
}
if (stack.realLength == 0) break;
memo.remove(ary);
tmp = stack.pop(context);
i = (int) ((RubyFixnum) tmp).getLongValue();
ary = (RubyArray) stack.pop(context);
if (stack == null || stack.size() == 0) break;
memo.remove(ary); // memo != null since stack != null
final int s = stack.size(); // pop (ary, i)
i = (Integer) stack.remove(s - 1);
ary = (RubyArray) stack.remove(s - 2);
}
} catch (ArrayIndexOutOfBoundsException ex) {
throw concurrentModification(context.runtime, ex);
}
return modified;
return stack != null;
}

@JRubyMethod(name = "flatten!")
Expand Down
46 changes: 27 additions & 19 deletions core/src/main/java/org/jruby/compiler/impl/SkinnyMethodAdapter.java
Expand Up @@ -563,35 +563,43 @@ public void start() {
getMethodVisitor().visitCode();
getMethodVisitor().visitLabel(start);
}


static final Runnable NO_LOCALS = new Runnable() { public void run() { /* no-op */ } };

public void end() {
end(new Runnable() {
public void run() {
}
});
end(NO_LOCALS);
}

public void end(Runnable locals) {
if (DEBUG) {
PrintWriter pw = new PrintWriter(System.out);
String className = "(unknown class)";
if (cv instanceof ClassWriter) {
className = new ClassReader(((ClassWriter)cv).toByteArray()).getClassName();
}
if (name != null) {
pw.write("*** Dumping " + className + "." + name + " ***\n");
} else {
pw.write("*** Dumping ***\n");
}
printer.print(pw);
pw.flush();
}
if (DEBUG) printByteCode(getClassName());
getMethodVisitor().visitLabel(end);
locals.run();
getMethodVisitor().visitMaxs(1, 1);
getMethodVisitor().visitEnd();
}

private String getClassName() {
if (cv instanceof ClassWriter) {
return new ClassReader(((ClassWriter) cv).toByteArray()).getClassName();
}
return "(unknown class)";
}

private PrintWriter outDebugWriter() {
return new PrintWriter(System.out);
}

private void printByteCode(final String className) {
PrintWriter pw = outDebugWriter();
if (name != null) {
pw.write("*** Dumping " + className + '.' + name + " ***\n");
} else {
pw.write("*** Dumping ***\n");
}
if (printer != null) printer.print(pw);
pw.flush();
}

public void local(int index, String name, Class type) {
getMethodVisitor().visitLocalVariable(name, ci(type), null, start, end, index);
}
Expand Down
Expand Up @@ -212,7 +212,7 @@ public static byte[] createHandleBytes(Method method, String name) {
private static String createHandleName(Method method) {
Class returnType = method.getReturnType();
Class[] paramTypes = method.getParameterTypes();
return method.getDeclaringClass().getCanonicalName().replaceAll("\\.", "__") + "#" + method.getName() + "#" + JITCompiler.getHashForString(pretty(returnType, paramTypes));
return method.getDeclaringClass().getCanonicalName().replaceAll("\\.", "__") + '#' + method.getName() + '#' + JITCompiler.getHashForString(pretty(returnType, paramTypes));
}

public static void loadUnboxedArgument(SkinnyMethodAdapter m, int index, Class type) {
Expand Down
9 changes: 7 additions & 2 deletions core/src/main/java/org/jruby/ext/JRubyPOSIXHandler.java
Expand Up @@ -72,12 +72,17 @@ public File getCurrentWorkingDirectory() {
@SuppressWarnings("unchecked")
public String[] getEnv() {
RubyHash hash = (RubyHash) runtime.getObject().getConstant("ENV");
int i=0;

String[] env = new String[hash.size()];
if (env.length == 0) return env;

StringBuilder str = new StringBuilder(); int i=0;

for (Iterator<Entry<Object, Object>> iter = hash.directEntrySet().iterator(); iter.hasNext(); i++) {
Map.Entry<Object, Object> entry = iter.next();
env[i] = entry.getKey().toString() + "=" + entry.getValue().toString();
str.setLength(0);
str.append(entry.getKey()).append('=').append(entry.getValue());
env[i] = str.toString();
}

return env;
Expand Down
10 changes: 9 additions & 1 deletion core/src/main/java/org/jruby/ext/bigdecimal/RubyBigDecimal.java
Expand Up @@ -442,8 +442,16 @@ public static RubyBigDecimal getVpRubyObjectWithPrec19Inner(ThreadContext contex
private static RubyBigDecimal getVpValueWithPrec19(ThreadContext context, IRubyObject value, long precision, boolean must) {
if (value instanceof RubyFloat) {
if (precision > Long.MAX_VALUE) return cannotBeCoerced(context, value, must);
double doubleValue = ((RubyFloat) value).getDoubleValue();

return new RubyBigDecimal(context.runtime, BigDecimal.valueOf(((RubyFloat) value).getDoubleValue()));
if (Double.isInfinite(doubleValue)) {
throw context.runtime.newFloatDomainError(doubleValue < 0 ? "-Infinity" : "Infinity");
}
if (Double.isNaN(doubleValue)) {
throw context.runtime.newFloatDomainError("NaN");
}

return new RubyBigDecimal(context.runtime, BigDecimal.valueOf(doubleValue));
}
else if (value instanceof RubyRational) {
if (precision < 0) {
Expand Down

0 comments on commit 87f774a

Please sign in to comment.