-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Throw a runtime error if #binding is called from a C extensions module (non-ruby frame) #3436
Open
manefz
wants to merge
1
commit into
oracle:master
Choose a base branch
from
Shopify:mz/binding-raises
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+7
−1
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
fails:CApiBindingSpecs Kernel#binding gives the top-most Ruby binding when called from C | ||
fails:CApiBindingSpecs Kernel#binding raises when called from C |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -334,6 +334,12 @@ RubyBinding binding(Frame callerFrame, Object self, Object[] rubyArgs, RootCallT | |
@Cached( | ||
value = "getAdoptedNode(this).getEncapsulatingSourceSection()", | ||
allowUncached = true, neverDefault = false) SourceSection sourceSection) { | ||
final InternalMethod method = RubyArguments.tryGetMethod(callerFrame); | ||
if (method == null || method.getDeclaringModule().toString().equals("Truffle::CExt")) { | ||
throw new RaiseException(getContext(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you use an |
||
coreExceptions().runtimeError("You cannot call Kernel#Binding from a non-ruby frame", this)); | ||
|
||
} | ||
needCallerFrame(callerFrame, target); | ||
return BindingNodes.createBinding(getContext(), getLanguage(), callerFrame.materialize(), sourceSection); | ||
} | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference it seems
tryGetMethod
is looking up the ruby method that is the context of the frame callingbinding
.So in the case of the test
truffleruby/spec/ruby/optional/capi/binding_spec.rb
Line 14 in 0c3f184
is backed by
truffleruby/spec/ruby/optional/capi/ext/binding_spec.c
Lines 8 to 9 in 0c3f184
and the method of the caller frame then points to
CExt#rb_funcallv
truffleruby/lib/truffle/truffle/cext.rb
Line 1059 in 0c3f184
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure in what scenario
tryGetMethod
might return nullThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's probably also a better check here than doing a string comparison on the method's module, but we hadn't found anything.
Any pointers on what else we might be able to use for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is
org.truffleruby.core.CoreLibrary#truffleCExtModule
and then it can be compared with==
.But comparing on the module is hacky, because it means every
Truffle::CExt
method can no longer accessbinding
.Which seems a problem notably for:
truffleruby/lib/truffle/truffle/cext.rb
Lines 2039 to 2041 in 610cea3
That can be worked around, but it shows it's rather hacky.
I'm not sure what's a good solution for detecting C ext methods, maybe/probably we should define
Truffle::CExt#rb_define_method
in Java eventually. Or find another way to mark those.But I think for now a more useful check would be to check if
sourceSection == CoreLibrary.JAVA_CORE_SOURCE_SECTION
, which means a method defined in Java.Getting a binding from there will always be empty, which seems not useful, so that seems the corresponding case to CRuby having methods defined in C and for which no meaningful binding can be given.
An example test for that is:
Currently on TruffleRuby it's:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW for the existing spec in spec/ruby/optional/capi/binding_spec.rb I would think we already raise an error for that case, because the callerFrame should be
null
in that case since it is a call from LLVM/Sulong.But maybe there is something in between which means there is a frame somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the master branch this spec fails with
I loaded a debugger to check the sourceSection and it is not the same as
CoreLibrary.JAVA_CORE_SOURCE_SECTION
.This is what I see:
If I use a different ruby script that calls binding from ruby code the sourceSection here doesn't have any different properties from the above (other than the
path
) that I can see 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, so the SourceSection there is
truffleruby/lib/truffle/truffle/cext.rb
Line 1060 in 677ac08
So let's not try to pass this specific spec for now, because it would require changing
rb_funcallv
which is out of scope.But instead let's add another spec, using
method(:binding).call
, and that should raise the RuntimeError, and that one we can use the check for JAVA_CORE_SOURCE_SECTION.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing worth trying to pass that C API spec would be to change
SendWithoutCExtLockBaseNode
to callcallWithFrameAndBlock
without aframe
(so withnull
instead). But that may have other side effects which might be undesirable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ but the frame was added back in 6fbb9ee probably for 796df16.
And 9c0f7ce seems also related.
So I think best to not touch that for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#3449 Is an alternative implementation that uses something similar to the commit you pointed to 9c0f7ce