Skip to content

Commit 897973d

Browse files
committed
[GR-44830] Only catch RaiseException for ReferenceProcessingService and improve defined?()
PullRequest: truffleruby/3876
2 parents 9a34952 + 89775c0 commit 897973d

File tree

5 files changed

+34
-10
lines changed

5 files changed

+34
-10
lines changed

spec/ruby/language/defined_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,32 @@
180180
ScratchPad.recorded.should == :defined_specs_fixnum_method
181181
end
182182
end
183+
184+
describe "having a throw in the receiver" do
185+
it "escapes defined? and performs the throw semantics as normal" do
186+
defined_returned = false
187+
catch(:out) {
188+
# NOTE: defined? behaves differently if it is called in a void context, see below
189+
defined?(throw(:out, 42).foo).should == :unreachable
190+
defined_returned = true
191+
}.should == 42
192+
defined_returned.should == false
193+
end
194+
end
195+
196+
describe "in a void context" do
197+
it "does not execute the receiver" do
198+
ScratchPad.record :not_executed
199+
defined?(DefinedSpecs.side_effects / 2)
200+
ScratchPad.recorded.should == :not_executed
201+
end
202+
203+
it "warns about the void context when parsing it" do
204+
-> {
205+
eval "defined?(DefinedSpecs.side_effects / 2); 42"
206+
}.should complain("(eval):1: warning: possibly useless use of defined? in void context\n", verbose: true)
207+
end
208+
end
183209
end
184210

185211
describe "The defined? keyword for an expression" do

spec/tags/language/defined_tags.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ fails:The defined? keyword for a variable scoped constant returns nil if the ins
88
fails:The defined? keyword for a variable scoped constant returns nil if the global scoped constant is not defined
99
fails:The defined? keyword for a variable scoped constant returns nil if the class scoped constant is not defined
1010
fails:The defined? keyword for a variable scoped constant returns nil if the local scoped constant is not defined
11+
fails:The defined? keyword when called with a method name in a void context warns about the void context when parsing it

src/main/java/org/truffleruby/core/ReferenceProcessingService.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.truffleruby.language.control.RaiseException;
2121

2222
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
23-
import org.truffleruby.language.control.TerminationException;
2423

2524
public abstract class ReferenceProcessingService<R extends ReferenceProcessingService.PhantomProcessingReference<R, T>, T> {
2625

@@ -168,13 +167,6 @@ protected void runCatchingErrors(RubyContext context, RubyLanguage language,
168167
action.accept(context, language, reference);
169168
} catch (RaiseException e) {
170169
context.getCoreExceptions().showExceptionIfDebug(e.getException());
171-
} catch (TerminationException e) {
172-
throw e;
173-
} catch (Exception e) {
174-
// Do nothing, the finalizer thread must continue to process objects.
175-
if (context.getCoreLibrary().getDebug() == Boolean.TRUE) {
176-
e.printStackTrace();
177-
}
178170
}
179171
}
180172

src/main/java/org/truffleruby/language/defined/DefinedNode.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public Object execute(VirtualFrame frame) {
2727
return child.isDefined(frame, getLanguage(), getContext());
2828
}
2929

30+
@Override
31+
public void doExecuteVoid(VirtualFrame frame) {
32+
// do nothing
33+
}
34+
3035
@Override
3136
public RubyNode cloneUninitialized() {
3237
var copy = new DefinedNode(child.cloneUninitialized());

src/main/java/org/truffleruby/language/dispatch/RubyCallNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.truffleruby.language.arguments.KeywordArgumentsDescriptorManager;
3030
import org.truffleruby.language.arguments.RubyArguments;
3131
import org.truffleruby.language.arguments.SplatToArgsNode;
32+
import org.truffleruby.language.control.RaiseException;
3233
import org.truffleruby.language.literal.NilLiteralNode;
3334
import org.truffleruby.language.methods.BlockDefinitionNode;
3435
import org.truffleruby.language.methods.InternalMethod;
@@ -321,10 +322,9 @@ public Object isDefined(VirtualFrame frame, RubyContext context) {
321322
allArgumentsDefinedProfile.enter();
322323

323324
final Object receiverObject;
324-
325325
try {
326326
receiverObject = receiver.execute(frame);
327-
} catch (Exception e) {
327+
} catch (RaiseException e) {
328328
receiverExceptionProfile.enter();
329329
return nil;
330330
}

0 commit comments

Comments
 (0)