Skip to content
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

Implement rb_frame_method_id_and_class internal API. #3363

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main/c/cext/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,7 @@ VALUE rb_eval_cmd_kw(VALUE cmd, VALUE args, int kw_splat) {
return RUBY_CEXT_INVOKE("rb_eval_string", cmd);
}
}

int rb_frame_method_id_and_class(ID *idp, VALUE *klassp) {
return RUBY_CEXT_INVOKE("rb_frame_method_id_and_class", idp, klassp);
}
Copy link
Member

Choose a reason for hiding this comment

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

We would need specs for this, under spec/ruby/optional/capi.
rb_frame_method_id_and_class is actually not a private function but it seems public C API, it's declared and documented in https://github.com/ruby/ruby/blob/fc48a679062e422b475ccea11574bf5b4368b732/include/ruby/internal/intern/vm.h#L62

31 changes: 31 additions & 0 deletions src/main/java/org/truffleruby/cext/CExtNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -2071,4 +2071,35 @@ RubyArray zlibGetCRCTable() {
}
}

@CoreMethod(names = "rb_frame_method_and_id", onSingleton = true, required = 2)
public abstract static class FrameMethodAndId extends CoreMethodArrayArgumentsNode {

@Specialization
boolean frameMethodAndId(Object frameMethod, Object frameId) {
final Frame callingMethodFrame = findCallingMethodFrame();
frameMethod = RubyArguments.getMethod(callingMethodFrame);
frameId = System.identityHashCode(RubyArguments.tryGetSelf(callingMethodFrame));
Copy link
Member

Choose a reason for hiding this comment

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

These assignments have no effect, they only assign the local Java variable, not the C pointer.
You need to return something which contains both (e.g. a Method Ruby object or a Ruby Array of two elements).

return true;
}

@TruffleBoundary
private static Frame findCallingMethodFrame() {
Copy link
Member

@eregon eregon Jan 3, 2024

Choose a reason for hiding this comment

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

I think org.truffleruby.language.CallStackManager#getCallingMethod should work instead of this and be a lot cleaner. And if not probably a variant of it.

return Truffle.getRuntime().iterateFrames(frameInstance -> {
final Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY);

final InternalMethod method = RubyArguments.tryGetMethod(frame);

if (method == null) {
return null;
} else if (method.getName().equals(/* Truffle::CExt. */ "rb_frame_method_and_id") ||
method.getName().equals(/* Truffle::Interop */ "execute_without_conversion")) {
// TODO CS 11-Mar-17 must have a more precise check to skip these methods
return null;
} else {
return frame;
}
});
}
}

}
Loading