Skip to content

Conversation

ssnickolay
Copy link
Collaborator

Related to #2120 (comment)

The test output before the PR changes:

1)
Kernel#respond_to? throws a type error if argument can't be coerced into a Symbol ERROR
Expected TypeError ((?-mix:is not a symbol nor a string))
but got: TypeError (TruffleRuby doesn't have a case for the org.truffleruby.core.kernel.KernelNodesFactory$RespondToNodeFactory$RespondToNodeGen node with values of type KernelSpecs::A(org.truffleruby.core.basicobject.RubyBasicObject) Object(org.truffleruby.core.basicobject.RubyBasicObject) java.lang.Boolean=false
	from org.truffleruby.core.kernel.KernelNodesFactory$RespondToNodeFactory$RespondToNodeGen.executeAndSpecialize(KernelNodesFactory.java:5238)
	from org.truffleruby.core.kernel.KernelNodesFactory$RespondToNodeFactory$RespondToNodeGen.execute(KernelNodesFactory.java:5210)
	from org.truffleruby.language.arguments.CheckArityNode.execute(CheckArityNode.java:41)
	from org.truffleruby.language.methods.ExceptionTranslatingNode.execute(ExceptionTranslatingNode.java:33)
	from org.truffleruby.language.RubyRootNode.execute(RubyRootNode.java:64)
	from com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:84))
/Users/ssnickolay/Projects/oss/graal/truffleruby-ws-2/truffleruby/spec/ruby/core/kernel/respond_to_spec.rb:28:in `respond_to?'

Not sure if I should add a note to the Changelog

if (notSymbolOrStringProfile.profile(!RubyGuards.isRubySymbolOrString(name))) {
throw new RaiseException(
getContext(),
coreExceptions().typeErrorIsNotAOrB(object.toString(), "symbol", "string", this));
Copy link
Member

@eregon eregon Oct 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toString() should not be called in PE code, because the receiver class is not known so it would be a virtual call, which is a performance warning.
So I'd suggest passing object to typeErrorIsNotAOrB() (then toString() is called behind a TruffleBoundary and that's OK).

We should probably use the new CoreException#inspectReceiver() helper there instead of toString(), but the PR adding it is not merged yet (should be soon).

Copy link
Collaborator Author

@ssnickolay ssnickolay Oct 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, it seems we have a few places with similar.toString():

protected long doBasicObject(Object value,
@CachedContext(RubyLanguage.class) RubyContext context) {
throw new RaiseException(
context,
context.getCoreExceptions().typeErrorIsNotA(value.toString(), "Integer (fitting in long)", this));

and

private RubyException notAnInteger(RubyContext context, Object object) {
return context.getCoreExceptions().typeErrorIsNotA(
object.toString(),

here we use Utils.toString():

protected int doBasicObject(Object value,
@CachedContext(RubyLanguage.class) RubyContext context) {
throw new RaiseException(
context,
context.getCoreExceptions().typeErrorIsNotA(Utils.toString(value), "Integer (fitting in int)", this));

Is this will be a part of

We should probably use the new CoreException#inspectReceiver() helper there instead of toString(), but the PR adding it is not merged yet (should be soon).

or we need to refactor these places too (probably not in this PR)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those cases are behind a @TruffleBoundary, so compilation-wise they are fine. The case here isn't.
I think -H:+TruffleCheckBlackListedMethods which is used in jt build --env native would actually detect as an error at image build time.

In terms of error message, inspectReceiver() is better. I used that to replace toString() in CoreExceptions, but not in other places (yet).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR I was talking about has been merged now, so if you rebase you can use inspectReceiver():
25eacca
As usual, new code should use the correct approach, but fixing old code is out of scope.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those cases are behind a @TruffleBoundary, so compilation-wise they are fine

Ah, that was obvious, sorry

The PR I was talking about has been merged now, so if you rebase you can use inspectReceiver():

No problem, but I should still pass Object over String, right?:

public RubyException typeErrorIsNotAOrB(Object value, String expectedTypeA, String expectedTypeB, Node currentNode) {
   # use inspectReceiver(value) instead of value.toString()

Copy link
Member

@eregon eregon Oct 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think in the future we should remove those cases where the receiver is typed as String, conversation should be done in CoreExeptions or later.

@eregon
Copy link
Member

eregon commented Oct 27, 2020

Not sure if I should add a note to the Changelog

You could add one like

* Fix error message when the method name is not a Symbol or String for `Kernel#respond_to?`

(the previous message was essentially a bug)

@eregon eregon added this to the 21.0.0 milestone Oct 27, 2020
@ssnickolay ssnickolay force-pushed the chore/refactor-kernel-respond-to branch from 618fc20 to c1fec78 Compare October 28, 2020 18:19
@ssnickolay
Copy link
Collaborator Author

@eregon the PR ready for the final review

@eregon
Copy link
Member

eregon commented Oct 29, 2020

Thank you for the refactoring!

graalvmbot pushed a commit that referenced this pull request Oct 29, 2020
@graalvmbot graalvmbot merged commit c1fec78 into oracle:master Oct 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants