Skip to content

Commit fb5586d

Browse files
committed
Merge remote-tracking branch 'origin/master' into 10.1-dev
2 parents a322ab5 + de4ee7e commit fb5586d

261 files changed

Lines changed: 4641 additions & 5063 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: JRuby CI
2+
3+
on: [push, pull_request]
4+
5+
env:
6+
JAVA_OPTS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xms60M -Xmx1G -XX:InitialCodeCacheSize=40M -XX:ReservedCodeCacheSize=120M'
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
13+
rake-test:
14+
runs-on: windows-latest
15+
16+
strategy:
17+
matrix:
18+
java-version: ['21', '25']
19+
fail-fast: false
20+
21+
name: windows verification (Java ${{ matrix.java-version }})
22+
23+
steps:
24+
- name: checkout
25+
uses: actions/checkout@v3
26+
- name: set up java ${{ matrix.java-version }}
27+
uses: actions/setup-java@v3
28+
with:
29+
distribution: 'zulu'
30+
java-version: ${{ matrix.java-version }}
31+
cache: 'maven'
32+
- name: bootstrap
33+
run: mvn -ntp -Pbootstrap clean package
34+
- name: bundle install
35+
run: bin/jruby --dev -S bundle install
36+
- name: jruby rails_runner
37+
shell: cmd
38+
run: |
39+
set PATH=%CD%\bin;%PATH%
40+
jruby tool/rails_runner

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ failures
2929
.debug.properties
3030
.redcar
3131
/.rbx/
32-
build
3332
build.properties
3433
build_graph.png
3534
core/src/main/java/org/jruby/runtime/Constants.java

bin/jruby.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,11 @@ for j in "$JRUBY_HOME"/lib/jruby.jar "$JRUBY_HOME"/lib/jruby-complete.jar; do
671671
fi
672672
jruby_jar="$j"
673673
done
674+
675+
if [ -z "${jruby_jar-}" ]; then
676+
echo "JRUBY_HOME at ${JRUBY_HOME} contains no lib/jruby.jar, exiting."
677+
exit 1
678+
fi
674679
readonly jruby_jar
675680

676681
if $cygwin; then

core/src/main/java/org/jruby/RubyData.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@
4040
import static org.jruby.runtime.Arity.checkArgumentCount;
4141
import static org.jruby.runtime.Helpers.invokedynamic;
4242
import static org.jruby.runtime.ThreadContext.CALL_KEYWORD;
43+
import static org.jruby.runtime.ThreadContext.CALL_KEYWORD_EMPTY;
4344
import static org.jruby.runtime.ThreadContext.clearCallInfo;
4445
import static org.jruby.runtime.ThreadContext.hasKeywords;
46+
import static org.jruby.runtime.ThreadContext.hasNonemptyKeywords;
4547
import static org.jruby.runtime.ThreadContext.resetCallInfo;
4648
import static org.jruby.runtime.invokedynamic.MethodNames.HASH;
4749
import static org.jruby.util.RubyStringBuilder.str;
@@ -309,7 +311,7 @@ public static IRubyObject rbNew(ThreadContext context, IRubyObject self, IRubyOb
309311

310312
RubyHash init;
311313
int callInfo = resetCallInfo(context);
312-
if (hasKeywords(callInfo)) {
314+
if (hasNonemptyKeywords(callInfo)) {
313315
if (!(hashOrElt instanceof RubyHash)) {
314316
throw argumentError(context, 1, 0, 0);
315317
}

core/src/main/java/org/jruby/RubyEnumerator.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,14 @@ private IRubyObject __each__(ThreadContext context, final Block block) {
329329
if (methodArgsHasKeywords) context.callInfo = CALL_KEYWORD;
330330
return object.callMethod(context, method, methodArgs,
331331
CallBlock.newCallClosure(context, this, Signature.OPTIONAL, (ctx, args, blk) -> {
332-
IRubyObject ret = block.yieldValues(ctx, args);
332+
IRubyObject ret;
333+
334+
if (args.length == 1) {
335+
ret = block.yield(ctx, args[0]);
336+
} else {
337+
ret = block.yieldValues(ctx, args);
338+
}
339+
333340
IRubyObject val = feedValue.use_value(ctx);
334341
return val.isNil() ? ret : val;
335342
})

core/src/main/java/org/jruby/RubyFloat.java

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -271,34 +271,8 @@ public static IRubyObject induced_from(ThreadContext context, IRubyObject recv,
271271
@JRubyMethod(name = {"to_s", "inspect"})
272272
@Override
273273
public IRubyObject to_s(ThreadContext context) {
274-
if (Double.isInfinite(value)) {
275-
return newSharedString(context, value < 0 ? NEGATIVE_INFINITY_TO_S_BYTELIST : POSITIVE_INFINITY_TO_S_BYTELIST);
276-
}
277-
if (Double.isNaN(value)) return newSharedString(context, NAN_TO_S_BYTELIST);
278-
279-
ByteList buf = new ByteList();
280-
// Under 1.9, use full-precision float formatting (JRUBY-4846).
281-
// Double-precision can represent around 16 decimal digits;
282-
// we use 20 to ensure full representation.
283-
Sprintf.sprintf(buf, Locale.US, "%#.20g", this);
284-
int e = buf.indexOf('e');
285-
if (e == -1) e = buf.getRealSize();
286-
ASCIIEncoding ascii = ASCIIEncoding.INSTANCE;
287-
288-
if (!ascii.isDigit(buf.get(e - 1))) {
289-
buf.setRealSize(0);
290-
Sprintf.sprintf(buf, Locale.US, "%#.14e", this);
291-
e = buf.indexOf('e');
292-
if (e == -1) e = buf.getRealSize();
293-
}
294-
295-
int p = e;
296-
while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
297-
System.arraycopy(buf.getUnsafeBytes(), e, buf.getUnsafeBytes(), p, buf.getRealSize() - e);
298-
buf.setRealSize(p + buf.getRealSize() - e);
299-
300-
buf.setEncoding(USASCIIEncoding.INSTANCE);
301-
274+
ByteList buf = new ByteList(24);
275+
formatFloat(this, buf);
302276
return newString(context, buf);
303277
}
304278

@@ -802,7 +776,7 @@ public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) {
802776

803777
RubyInteger two_times_f = (RubyInteger) rf.op_mul(context, 2);
804778
den = (RubyInteger) one.op_lshift(context, one.op_minus(context, n));
805-
779+
806780
a = RubyRational.newRationalRaw(runtime, two_times_f.op_minus(context, 1), den);
807781
b = RubyRational.newRationalRaw(runtime, two_times_f.op_plus(context, 1), den);
808782
}
@@ -1141,6 +1115,47 @@ private ByteList marshalDump(ThreadContext context) {
11411115
return byteList;
11421116
}
11431117

1118+
public static ByteList formatFloat(RubyFloat self, ByteList buf) {
1119+
buf.setRealSize(0);
1120+
1121+
double value = self.value;
1122+
1123+
if (Double.isInfinite(value)) {
1124+
buf.append(value < 0
1125+
? NEGATIVE_INFINITY_TO_S_BYTELIST
1126+
: POSITIVE_INFINITY_TO_S_BYTELIST);
1127+
buf.setEncoding(USASCIIEncoding.INSTANCE);
1128+
return buf;
1129+
}
1130+
1131+
if (Double.isNaN(value)) {
1132+
buf.append(NAN_TO_S_BYTELIST);
1133+
buf.setEncoding(USASCIIEncoding.INSTANCE);
1134+
return buf;
1135+
}
1136+
1137+
Sprintf.sprintf(buf, Locale.US, "%#.20g", self);
1138+
1139+
int e = buf.indexOf('e');
1140+
if (e == -1) e = buf.getRealSize();
1141+
ASCIIEncoding ascii = ASCIIEncoding.INSTANCE;
1142+
1143+
if (!ascii.isDigit(buf.get(e - 1))) {
1144+
buf.setRealSize(0);
1145+
Sprintf.sprintf(buf, Locale.US, "%#.14e", self);
1146+
e = buf.indexOf('e');
1147+
if (e == -1) e = buf.getRealSize();
1148+
}
1149+
1150+
int p = e;
1151+
while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
1152+
System.arraycopy(buf.getUnsafeBytes(), e, buf.getUnsafeBytes(), p, buf.getRealSize() - e);
1153+
buf.setRealSize(p + buf.getRealSize() - e);
1154+
1155+
buf.setEncoding(USASCIIEncoding.INSTANCE);
1156+
return buf;
1157+
}
1158+
11441159
@Deprecated(since = "10.0.0.0", forRemoval = true)
11451160
@SuppressWarnings("removal")
11461161
public static void marshalTo(RubyFloat aFloat, org.jruby.runtime.marshal.MarshalStream output) throws java.io.IOException {

core/src/main/java/org/jruby/RubyGlobal.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public static RubyHash createGlobalsAndENV(ThreadContext context, GlobalVariable
167167
Object.defineConstant(context, "RUBY_RELEASE_DATE", release);
168168
Object.defineConstant(context, "RUBY_PLATFORM", platform);
169169

170-
IRubyObject description = RubyString.newFString(runtime, OutputStrings.getVersionString());
170+
IRubyObject description = RubyString.newFString(runtime, OutputStrings.getVersionString(instanceConfig));
171171
Object.defineConstant(context, "RUBY_DESCRIPTION", description);
172172

173173
IRubyObject copyright = RubyString.newFString(runtime, OutputStrings.getCopyrightString());

core/src/main/java/org/jruby/RubyHash.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,6 +2488,11 @@ public RubyHash dupFast(final ThreadContext context) {
24882488
return dup;
24892489
}
24902490

2491+
public RubyHash withRuby2Keywords(boolean ruby2Keywords) {
2492+
setRuby2KeywordHash(ruby2Keywords);
2493+
return this;
2494+
}
2495+
24912496
public boolean hasDefaultProc() {
24922497
return (hashFlags & PROCDEFAULT_HASH) != 0;
24932498
}

core/src/main/java/org/jruby/RubyModule.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ String anonymousMetaNameWithIdentifier(ThreadContext context) {
10261026
return metaClass.getRealClass().getName(context) + ":0x" + Integer.toHexString(System.identityHashCode(this));
10271027
}
10281028

1029-
@JRubyMethod(name = "refine", reads = SCOPE)
1029+
@JRubyMethod(name = "refine", visibility = PRIVATE, reads = SCOPE)
10301030
public IRubyObject refine(ThreadContext context, IRubyObject klass, Block block) {
10311031
if (!block.isGiven()) throw argumentError(context, "no block given");
10321032
if (block.isEscaped()) throw argumentError(context, "can't pass a Proc as a block to Module#refine");
@@ -1976,9 +1976,7 @@ public final void addMethodInternal(ThreadContext context, String name, DynamicM
19761976
putMethod(context, name, method);
19771977
}
19781978

1979-
synchronized (getRuntime().getHierarchyLock()) {
1980-
invalidateCacheDescendants(context);
1981-
}
1979+
invalidateMethodCache(context);
19821980
}
19831981

19841982
public void removeMethod(ThreadContext context, String id) {
@@ -2414,6 +2412,17 @@ public void invalidateCacheDescendants(ThreadContext context) {
24142412
methodInvalidator.invalidateAll(invalidators);
24152413
}
24162414

2415+
/**
2416+
* Invalidate the method cache of this class and all descendants under lock.
2417+
*
2418+
* @param context
2419+
*/
2420+
public void invalidateMethodCache(ThreadContext context) {
2421+
synchronized (getRuntime().getHierarchyLock()) {
2422+
invalidateCacheDescendants(context);
2423+
}
2424+
}
2425+
24172426
public static class InvalidatorList<T> extends ArrayList<T> implements RubyClass.BiConsumerIgnoresSecond<RubyClass> {
24182427
public InvalidatorList(int size) {
24192428
super(size);
@@ -6879,6 +6888,7 @@ public static IRubyObject import_methods(ThreadContext context, IRubyObject self
68796888

68806889
for (IRubyObject _module : modules) {
68816890
RubyModule module = castAsModule(context, _module);
6891+
if (module.getClass() != RubyModule.class) throw typeError(context, "wrong argument type Class (expected Module)");
68826892

68836893
if (module.getSuperClass() != null) {
68846894
warn(context, module.getName(context) + " has ancestors, but Refinement#import_methods doesn't import their methods");
@@ -6906,6 +6916,7 @@ private static void refinementImportMethodsIter(ThreadContext context, RubyModul
69066916
}
69076917

69086918
DynamicMethod dup = entry.getValue().dup();
6919+
dup.setImplementationClass(selfModule);
69096920

69106921
// maybe insufficient if we have already compiled assuming no refinements
69116922
((AbstractIRMethod) dup).getIRScope().setIsMaybeUsingRefinements();

core/src/main/java/org/jruby/RubyStruct.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import static org.jruby.runtime.Helpers.invokedynamic;
7272
import static org.jruby.runtime.ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR;
7373
import static org.jruby.runtime.ThreadContext.hasKeywords;
74+
import static org.jruby.runtime.ThreadContext.hasNonemptyKeywords;
7475
import static org.jruby.runtime.Visibility.PRIVATE;
7576
import static org.jruby.runtime.invokedynamic.MethodNames.HASH;
7677
import static org.jruby.RubyEnumerator.SizeFn;
@@ -531,7 +532,7 @@ public IRubyObject initialize(ThreadContext context) {
531532

532533
@JRubyMethod(visibility = PRIVATE)
533534
public IRubyObject initialize(ThreadContext context, IRubyObject arg0) {
534-
boolean keywords = hasKeywords(ThreadContext.resetCallInfo(context));
535+
boolean keywords = hasNonemptyKeywords(ThreadContext.resetCallInfo(context));
535536

536537
if (keywords) {
537538
return setupStructValuesFromHash(context, (RubyHash) arg0);

0 commit comments

Comments
 (0)