Skip to content

Commit 3c116ac

Browse files
authored
Merge pull request jruby#9302 from kares/kares-10.0_kwargs-call-info_clean
review call-info reset in all places with `@JRubyMethod` `keywords = true`
2 parents 8392664 + c4cfc0e commit 3c116ac

18 files changed

Lines changed: 500 additions & 107 deletions

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

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@
7878
import static org.jruby.api.Define.defineClass;
7979
import static org.jruby.api.Error.argumentError;
8080
import static org.jruby.api.Warn.warn;
81-
import static org.jruby.runtime.ThreadContext.CALL_KEYWORD;
82-
import static org.jruby.runtime.ThreadContext.resetCallInfo;
81+
import static org.jruby.runtime.ThreadContext.hasKeywords;
8382
import static org.jruby.runtime.Visibility.PRIVATE;
8483

8584
public class RubyArgsFile extends RubyObject {
@@ -389,9 +388,7 @@ public static IRubyObject external_encoding(ThreadContext context, IRubyObject r
389388
}
390389

391390
// MRI: argf_getline
392-
private static IRubyObject argf_getline(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
393-
int callInfo = resetCallInfo(context);
394-
boolean keywords = (callInfo & CALL_KEYWORD) != 0;
391+
private static IRubyObject argf_getline(ThreadContext context, final int callInfo, IRubyObject[] args) {
395392
IRubyObject line;
396393
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);
397394

@@ -401,14 +398,13 @@ private static IRubyObject argf_getline(ThreadContext context, IRubyObject recv,
401398
RubyIO currentFile = (RubyIO) data.currentFile;
402399

403400
if (isGenericInput(context, data)) {
404-
// restore callInfo for kwargs
405-
context.callInfo = callInfo;
401+
context.callInfo = callInfo; // restore callInfo for kwargs
406402
line = data.currentFile.callMethod(context, "gets", args);
407403
} else {
408404
if (args.length == 0 && context.runtime.getRecordSeparatorVar().get() == globalVariables(context).getDefaultSeparator()) {
409405
line = (currentFile).gets(context);
410406
} else {
411-
line = Getline.getlineCall(context, GETLINE, currentFile, currentFile.getReadEncoding(), keywords, args);
407+
line = Getline.getlineCall(context, GETLINE, currentFile, currentFile.getReadEncoding(), hasKeywords(callInfo), args);
412408
}
413409

414410
if (line.isNil() && data.next_p != Stream) {
@@ -436,9 +432,10 @@ private static boolean isGenericInput(ThreadContext context, ArgsFileData data)
436432
*/
437433
@JRubyMethod(name = "gets", optional = 1, keywords = true, checkArity = false, writes = LASTLINE)
438434
public static IRubyObject gets(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
435+
final int callInfo = ThreadContext.resetCallInfo(context);
439436
Arity.checkArgumentCount(context, args, 0, 1);
440437

441-
return context.setLastLine(argf_getline(context, recv, args));
438+
return context.setLastLine(argf_getline(context, callInfo, args));
442439
}
443440

444441
/** Read a line.
@@ -455,36 +452,26 @@ public static IRubyObject readline(ThreadContext context, IRubyObject recv, IRub
455452

456453
@JRubyMethod(optional = 1, keywords = true, checkArity = false)
457454
public static IRubyObject readlines(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
455+
final int callInfo = ThreadContext.resetCallInfo(context);
458456
Arity.checkArgumentCount(context, args, 0, 1);
459457

460-
int callInfo = context.callInfo;
461458
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);
462459

463460
if (!data.next_argv(context)) return newEmptyArray(context);
464461

465-
if (!(data.currentFile instanceof RubyIO)) return data.currentFile.callMethod(context, "readlines", args);
462+
if (!(data.currentFile instanceof RubyIO)) {
463+
// TODO do we need to restore callInfo here?
464+
return data.currentFile.callMethod(context, "readlines", args);
465+
}
466466

467467
var ary = newArray(context);
468468
IRubyObject line;
469-
while(!(line = argfGetlineLoopWithKeywords(context, recv, args, callInfo)).isNil()) {
469+
while(!(line = argf_getline(context, callInfo, args)).isNil()) {
470470
ary.append(context, line);
471471
}
472472
return ary;
473473
}
474474

475-
/**
476-
* Call argf_getline as in a loop, providing the given keywords state between calls.
477-
*
478-
* @param context
479-
* @param recv
480-
* @param args
481-
* @return
482-
*/
483-
private static IRubyObject argfGetlineLoopWithKeywords(ThreadContext context, IRubyObject recv, IRubyObject[] args, int callInfo) {
484-
context.callInfo = callInfo;
485-
return argf_getline(context, recv, args);
486-
}
487-
488475
@JRubyMethod(optional = 1, checkArity = false)
489476
public static IRubyObject to_a(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
490477
Arity.checkArgumentCount(context, args, 0, 1);
@@ -496,7 +483,7 @@ public static IRubyObject to_a(ThreadContext context, IRubyObject recv, IRubyObj
496483

497484
var ary = newArray(context);
498485
IRubyObject line;
499-
while ((line = argf_getline(context, recv, args)) != context.nil) {
486+
while ((line = argf_getline(context, 0, args)) != context.nil) {
500487
ary.append(context, line);
501488
}
502489
return ary;
@@ -601,9 +588,9 @@ public static IRubyObject codepoints(ThreadContext context, IRubyObject recv, Bl
601588
public static IRubyObject each_line(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) {
602589
if (!block.isGiven()) return enumeratorize(context.runtime, recv, "each_line", args);
603590

591+
final int callInfo = ThreadContext.resetCallInfo(context);
604592
Arity.checkArgumentCount(context, args, 0, 1);
605593

606-
int callInfo = context.callInfo;
607594
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);
608595

609596
if (!data.next_argv(context)) return context.nil;
@@ -616,7 +603,7 @@ public static IRubyObject each_line(ThreadContext context, IRubyObject recv, IRu
616603
}
617604

618605
IRubyObject str;
619-
while ((str = argfGetlineLoopWithKeywords(context, recv, args, callInfo)) != context.nil) {
606+
while ((str = argf_getline(context, callInfo, args)) != context.nil) {
620607
block.yield(context, str);
621608
}
622609

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

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,7 @@
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;
44-
import static org.jruby.runtime.ThreadContext.clearCallInfo;
45-
import static org.jruby.runtime.ThreadContext.hasKeywords;
4643
import static org.jruby.runtime.ThreadContext.hasNonemptyKeywords;
47-
import static org.jruby.runtime.ThreadContext.resetCallInfo;
4844
import static org.jruby.runtime.invokedynamic.MethodNames.HASH;
4945
import static org.jruby.util.RubyStringBuilder.str;
5046

@@ -88,14 +84,14 @@ public static RubyClass define(ThreadContext context, IRubyObject self, IRubyObj
8884

8985
@JRubyMethod(keywords = true, rest = true)
9086
public static void initialize(ThreadContext context, IRubyObject self, IRubyObject[] args) {
87+
ThreadContext.resetCallInfo(context); // we don't directly use callInfo here
88+
9189
RubyBasicObject selfObj = (RubyBasicObject) self;
90+
9291
selfObj.checkFrozen();
9392
RubyArray<RubySymbol> members = getStructMembers(self);
9493
int numMembers = members.size();
9594

96-
// we don't directly use callInfo here
97-
ThreadContext.clearCallInfo(context);
98-
9995
if (args.length == 0) {
10096
if (numMembers > 0) {
10197
throw keywordError(context, "missing", members);
@@ -243,7 +239,7 @@ public static RubyHash deconstruct_keys(ThreadContext context, IRubyObject self,
243239
@JRubyMethod(keywords = true, optional = 1, checkArity = false)
244240
public static IRubyObject with(ThreadContext context, IRubyObject self, IRubyObject[] args) {
245241
IRubyObject kwargs = IRRuntimeHelpers.receiveKeywords(context, args, false, true, false);
246-
if (kwargs == UndefinedValue.UNDEFINED || kwargs.isNil()) {
242+
if (!(kwargs instanceof RubyHash)) {
247243
checkArgumentCount(context, args.length, 0, 0);
248244
return self;
249245
}
@@ -253,7 +249,7 @@ public static IRubyObject with(ThreadContext context, IRubyObject self, IRubyObj
253249
RubyHash kwargsHash = (RubyHash) kwargs;
254250
RubyHash h = to_h(context, self, Block.NULL_BLOCK);
255251
h.addAll(context, kwargsHash);
256-
setCallInfo(context, CALL_KEYWORD);
252+
context.callInfo = CALL_KEYWORD;
257253
return DataMethods.rbNew(context, self.getMetaClass(), h);
258254
}
259255

@@ -281,7 +277,7 @@ public static IRubyObject rbNew(ThreadContext context, IRubyObject self, IRubyOb
281277

282278
IRubyObject dataObject = klass.getAllocator().allocate(context.runtime, klass);
283279

284-
setCallInfo(context, ThreadContext.CALL_KEYWORD);
280+
context.callInfo = ThreadContext.CALL_KEYWORD;
285281

286282
// TODO: avoid initialize and hash overhead for known types
287283
dataObject.getMetaClass().getBaseCallSite(RubyClass.CS_IDX_INITIALIZE)
@@ -293,10 +289,9 @@ public static IRubyObject rbNew(ThreadContext context, IRubyObject self, IRubyOb
293289

294290
@JRubyMethod(name = {"new", "[]"}, keywords = true)
295291
public static IRubyObject rbNew(ThreadContext context, IRubyObject self) {
296-
RubyClass klass = (RubyClass) self;
297-
298-
clearCallInfo(context);
292+
ThreadContext.resetCallInfo(context);
299293

294+
RubyClass klass = (RubyClass) self;
300295
IRubyObject dataObject = klass.getAllocator().allocate(context.runtime, klass);
301296

302297
dataObject.getMetaClass().getBaseCallSite(RubyClass.CS_IDX_INITIALIZE)
@@ -307,10 +302,10 @@ public static IRubyObject rbNew(ThreadContext context, IRubyObject self) {
307302

308303
@JRubyMethod(name = {"new", "[]"}, keywords = true)
309304
public static IRubyObject rbNew(ThreadContext context, IRubyObject self, IRubyObject hashOrElt) {
310-
RubyClass klass = (RubyClass) self;
305+
int callInfo = ThreadContext.resetCallInfo(context);
311306

307+
RubyClass klass = (RubyClass) self;
312308
RubyHash init;
313-
int callInfo = resetCallInfo(context);
314309
if (hasNonemptyKeywords(callInfo)) {
315310
if (!(hashOrElt instanceof RubyHash)) {
316311
throw argumentError(context, 1, 0, 0);
@@ -331,7 +326,7 @@ public static IRubyObject rbNew(ThreadContext context, IRubyObject self, IRubyOb
331326

332327
IRubyObject dataObject = klass.getAllocator().allocate(context.runtime, klass);
333328

334-
setCallInfo(context, callInfo);
329+
context.callInfo = callInfo;
335330

336331
// TODO: avoid initialize and hash overhead for known types
337332
dataObject.getMetaClass().getBaseCallSite(RubyClass.CS_IDX_INITIALIZE)

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,6 @@ private static class GlobOptions {
234234
private static void globOptions(ThreadContext context, IRubyObject[] args, String[] keys, GlobOptions options) {
235235
Ruby runtime = context.runtime;
236236

237-
// just clear callInfo for now; future PR will handle it appropriately
238-
ThreadContext.resetCallInfo(context);
239-
240237
if (args.length > 1) {
241238
IRubyObject tmp = TypeConverter.checkHashType(runtime, args[args.length - 1]);
242239
boolean processFlags = keys == BASE_FLAGS_KEYWORDS;
@@ -277,6 +274,7 @@ private static void globOptions(ThreadContext context, IRubyObject[] args, Strin
277274

278275
@JRubyMethod(name = "[]", rest = true, meta = true, keywords = true)
279276
public static IRubyObject aref(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
277+
ThreadContext.resetCallInfo(context);
280278
Ruby runtime = context.runtime;
281279
GlobOptions options = new GlobOptions();
282280
globOptions(context, args, BASE_KEYWORDS, options);
@@ -324,8 +322,9 @@ private static ByteList globArgumentAsByteList(ThreadContext context, IRubyObjec
324322
* with each filename is passed to the block in turn. In this case, Nil is
325323
* returned.
326324
*/
327-
@JRubyMethod(required = 1, optional = 2, checkArity = false, meta = true)
325+
@JRubyMethod(required = 1, optional = 2, checkArity = false, meta = true, keywords = true)
328326
public static IRubyObject glob(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) {
327+
ThreadContext.resetCallInfo(context);
329328
Arity.checkArgumentCount(context, args, 1, 3);
330329

331330
Ruby runtime = context.runtime;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import static org.jruby.runtime.Helpers.arrayOf;
5353
import static org.jruby.runtime.ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR;
5454
import static org.jruby.runtime.ThreadContext.CALL_KEYWORD;
55+
import static org.jruby.runtime.ThreadContext.hasNonemptyKeywords;
5556
import static org.jruby.runtime.Visibility.PRIVATE;
5657

5758
/**
@@ -209,10 +210,9 @@ public static IRubyObject enumeratorize(Ruby runtime, RubyClass type, IRubyObjec
209210
// and used internally to create enum from Enumerator::Lazy#eager
210211
@JRubyMethod(name = "__from", meta = true, required = 2, optional = 2, checkArity = false, visibility = PRIVATE, keywords = true)
211212
public static IRubyObject __from(ThreadContext context, IRubyObject klass, IRubyObject[] args) {
212-
int argc = Arity.checkArgumentCount(context, args, 2, 4);
213+
boolean keywords = hasNonemptyKeywords(ThreadContext.resetCallInfo(context));
213214

214-
boolean keywords = (context.callInfo & CALL_KEYWORD) != 0 && (context.callInfo & ThreadContext.CALL_KEYWORD_EMPTY) == 0;
215-
ThreadContext.resetCallInfo(context);
215+
int argc = Arity.checkArgumentCount(context, args, 2, 4);
216216

217217
// Lazy.__from(enum, method, *args, size)
218218
IRubyObject object = args[0];

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public IRubyObject flock(ThreadContext context, IRubyObject operation) {
299299
@JRubyMethod(name = "initialize", required = 1, optional = 3, checkArity = false, visibility = PRIVATE, keywords = true)
300300
public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block block) {
301301
// capture callInfo for delegating to IO#initialize
302-
int callInfo = context.callInfo;
302+
final int callInfo = context.callInfo;
303303
IRubyObject keywords = IRRuntimeHelpers.receiveKeywords(context, args, false, true, false);
304304
// Mild hack. We want to arity-mismatch if extra arg is not really a kwarg but not if it is one.
305305
int maxArgs = keywords instanceof RubyHash ? 4 : 3;
@@ -311,7 +311,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block b
311311
IRubyObject fd = TypeConverter.convertToTypeWithCheck(context, args[0], context.runtime.getFixnum(), sites(context).to_int_checked);
312312
if (!fd.isNil()) {
313313
// restore callInfo for delegated call to IO#initialize
314-
IRRuntimeHelpers.setCallInfo(context, callInfo);
314+
context.callInfo = callInfo;
315315
return switch (argc) {
316316
case 1 -> super.initialize(context, fd, block);
317317
case 2 -> super.initialize(context, fd, args[1], block);

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@
9292
import static org.jruby.api.Error.*;
9393
import static org.jruby.api.Warn.warn;
9494
import static org.jruby.runtime.ThreadContext.hasKeywords;
95-
import static org.jruby.runtime.ThreadContext.resetCallInfo;
9695
import static org.jruby.runtime.Visibility.PRIVATE;
9796
import static org.jruby.util.Inspector.*;
9897

@@ -813,9 +812,9 @@ public IRubyObject initialize(ThreadContext context, final Block block) {
813812
return this;
814813
}
815814

816-
@JRubyMethod(visibility = PRIVATE)
815+
@JRubyMethod(visibility = PRIVATE, keywords = true)
817816
public IRubyObject initialize(ThreadContext context, IRubyObject _default, final Block block) {
818-
boolean keywords = hasKeywords(resetCallInfo(context));
817+
boolean keywords = hasKeywords(ThreadContext.resetCallInfo(context));
819818
modify();
820819

821820
if (keywords) {
@@ -840,7 +839,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject _default, final
840839

841840
@JRubyMethod(visibility = PRIVATE, keywords = true)
842841
public IRubyObject initialize(ThreadContext context, IRubyObject _default, IRubyObject hash, final Block block) {
843-
if (!hasKeywords(resetCallInfo(context))) throw argumentError(context, 2, 0, 1);
842+
if (!hasKeywords(ThreadContext.resetCallInfo(context))) throw argumentError(context, 2, 0, 1);
844843

845844
IRubyObject[] opts = ArgsUtil.extractKeywordArgs(context, (RubyHash) hash, "capacity");
846845

0 commit comments

Comments
 (0)