Skip to content

Commit 55e6884

Browse files
committed
[GR-19220] Fix incorrect arity for C-extension methods (#2275)
PullRequest: truffleruby/2459
2 parents 3d0da02 + 4404e45 commit 55e6884

File tree

4 files changed

+61
-13
lines changed

4 files changed

+61
-13
lines changed

lib/truffle/truffle/cext_ruby.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ def rb_define_method(mod, name, function, argc)
4343
res
4444
end
4545

46-
mod.define_method(name, method_body)
46+
# Even if the argc is -2, the arity number
47+
# is still any number of arguments, -1
48+
arity = argc == -2 ? -1 : argc
49+
50+
method_body_with_arity = Primitive.proc_specify_arity(method_body, arity)
51+
mod.define_method(name, method_body_with_arity)
4752
end
4853

4954
private

src/main/java/org/truffleruby/core/proc/ProcNodes.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.truffleruby.language.control.RaiseException;
3535
import org.truffleruby.language.dispatch.DispatchNode;
3636
import org.truffleruby.language.locals.FindDeclarationVariableNodes.FindAndReadDeclarationVariableNode;
37+
import org.truffleruby.language.methods.Arity;
38+
import org.truffleruby.language.methods.SharedMethodInfo;
3739
import org.truffleruby.language.objects.AllocationTracing;
3840
import org.truffleruby.language.yield.CallBlockNode;
3941
import org.truffleruby.parser.ArgumentDescriptor;
@@ -256,19 +258,32 @@ public abstract static class ProcCreateSameArityNode extends PrimitiveArrayArgum
256258

257259
@Specialization
258260
protected RubyProc createSameArityProc(RubyProc userProc, RubyProc block) {
259-
final RubyProc composedProc = new RubyProc(
260-
coreLibrary().procClass,
261-
getLanguage().procShape,
262-
block.type,
261+
final RubyProc composedProc = block.withSharedMethodInfo(
263262
userProc.sharedMethodInfo,
264-
block.callTargets,
265-
block.callTarget,
266-
block.declarationFrame,
267-
block.declarationVariables,
268-
block.method,
269-
block.block,
270-
block.frameOnStackMarker,
271-
block.declarationContext);
263+
coreLibrary().procClass,
264+
getLanguage().procShape);
265+
AllocationTracing.trace(composedProc, this);
266+
return composedProc;
267+
}
268+
}
269+
270+
@Primitive(name = "proc_specify_arity", lowerFixnum = 1)
271+
public abstract static class ProcSpecifyArityNode extends PrimitiveArrayArgumentsNode {
272+
@Specialization
273+
protected RubyProc specifyArityProc(RubyProc block, int argc) {
274+
Arity oldArity = block.sharedMethodInfo.getArity();
275+
final Arity newArity;
276+
if (argc <= -1) {
277+
newArity = new Arity(-(argc + 1), 0, true);
278+
} else {
279+
newArity = new Arity(argc, 0, false);
280+
}
281+
282+
SharedMethodInfo newSharedMethodInfo = block.sharedMethodInfo.withArity(newArity);
283+
final RubyProc composedProc = block.withSharedMethodInfo(
284+
newSharedMethodInfo,
285+
coreLibrary().procClass,
286+
getLanguage().procShape);
272287
AllocationTracing.trace(composedProc, this);
273288
return composedProc;
274289
}

src/main/java/org/truffleruby/core/proc/RubyProc.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,22 @@ public RubyProc(
7474
this.declarationContext = declarationContext;
7575
}
7676

77+
public RubyProc withSharedMethodInfo(SharedMethodInfo newSharedMethodInfo, RubyClass newRubyClass, Shape newShape) {
78+
return new RubyProc(
79+
newRubyClass,
80+
newShape,
81+
type,
82+
newSharedMethodInfo,
83+
callTargets,
84+
callTarget,
85+
declarationFrame,
86+
declarationVariables,
87+
method,
88+
block,
89+
frameOnStackMarker,
90+
declarationContext);
91+
}
92+
7793
@Override
7894
public void getAdjacentObjects(Set<Object> reachable) {
7995
ObjectGraph.getObjectsInFrame(declarationFrame, reachable);

src/main/java/org/truffleruby/language/methods/SharedMethodInfo.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ public SharedMethodInfo convertMethodMissingToMethod(RubyModule declaringModule,
9191
newArgs);
9292
}
9393

94+
public SharedMethodInfo withArity(Arity newArity) {
95+
return new SharedMethodInfo(
96+
sourceSection,
97+
lexicalScope,
98+
newArity,
99+
backtraceName,
100+
blockDepth,
101+
parseName,
102+
notes,
103+
argumentDescriptors);
104+
}
105+
94106
public SourceSection getSourceSection() {
95107
return sourceSection;
96108
}

0 commit comments

Comments
 (0)