Skip to content

Commit b46b9b7

Browse files
committed
[GR-28775] Implement rb_lastline_set.
PullRequest: truffleruby/2330
2 parents addc7b7 + 5f0bb2f commit b46b9b7

File tree

5 files changed

+56
-4
lines changed

5 files changed

+56
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Compatibility:
4343
* Fixed `Integer#digits` implementation to handle more bases (#2224, #2225).
4444
* Support the `inherit` parameter for `Module#{private, protected, public}_method_defined?`.
4545
* Implement `Thread.pending_interrupt?` and `Thread#pending_interrupt?` (#2219).
46+
* Implement `rb_lastline_set` (#2170).
4647

4748
Performance:
4849

lib/truffle/truffle/cext.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,4 +1840,14 @@ def rb_thread_current_backtrace_locations
18401840
def rb_syserr_new(errno, mesg)
18411841
SystemCallError.new(mesg, errno)
18421842
end
1843+
1844+
def rb_lastline_set(str)
1845+
storage = Primitive.ruby_caller_special_variables
1846+
Primitive.io_last_line_set(storage, str)
1847+
end
1848+
1849+
def rb_lastline_get
1850+
storage = Primitive.ruby_caller_special_variables
1851+
Primitive.io_last_line_get(storage)
1852+
end
18431853
end

spec/tags/optional/capi/globals_tags.txt

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/main/c/cext/io.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,12 @@ void rb_io_set_nonblock(rb_io_t *fptr) {
194194
FILE *rb_io_stdio_file(rb_io_t *fptr) {
195195
rb_tr_error("rb_io_stdio_file not yet implemented");
196196
}
197+
198+
VALUE rb_lastline_get(void) {
199+
return RUBY_CEXT_INVOKE("rb_lastline_get");
200+
}
201+
202+
void rb_lastline_set(VALUE str) {
203+
RUBY_CEXT_INVOKE_NO_WRAP("rb_lastline_set", str);
204+
}
205+

src/main/java/org/truffleruby/core/kernel/TruffleKernelNodes.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,17 @@
5353
import com.oracle.truffle.api.dsl.NodeChild;
5454
import com.oracle.truffle.api.dsl.Specialization;
5555
import com.oracle.truffle.api.frame.FrameDescriptor;
56+
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
5657
import com.oracle.truffle.api.frame.FrameSlot;
5758
import com.oracle.truffle.api.frame.FrameSlotKind;
5859
import com.oracle.truffle.api.frame.FrameUtil;
5960
import com.oracle.truffle.api.frame.MaterializedFrame;
6061
import com.oracle.truffle.api.frame.VirtualFrame;
6162
import com.oracle.truffle.api.nodes.IndirectCallNode;
63+
import com.oracle.truffle.api.nodes.Node;
64+
import com.oracle.truffle.api.nodes.RootNode;
6265
import com.oracle.truffle.api.profiles.ConditionProfile;
66+
import com.oracle.truffle.api.Truffle;
6367

6468
@CoreModule("Truffle::KernelOperations")
6569
public abstract class TruffleKernelNodes {
@@ -323,6 +327,38 @@ protected Object storage(VirtualFrame frame) {
323327
}
324328
}
325329

330+
/* When getting special variables from the wrong side of a C call we know it's going to be slow. */
331+
@Primitive(name = "ruby_caller_special_variables")
332+
public abstract static class GetSlowCallerSpecialVariableStorage extends PrimitiveArrayArgumentsNode {
333+
334+
@Child GetSpecialVariableStorage getStorageNode = GetSpecialVariableStorage.create();
335+
336+
@Specialization
337+
@TruffleBoundary
338+
protected Object storage() {
339+
return getStorageNode.execute(Truffle.getRuntime().iterateFrames(frameInstance -> {
340+
final Node callNode = frameInstance.getCallNode();
341+
342+
if (callNode != null) {
343+
final RootNode rootNode = callNode.getRootNode();
344+
// Skip Ruby frames in cext.rb file since they are implementing methods which are implemented
345+
// with C in MRI, and therefore are also implicitly skipped when when looking up the block passed
346+
// to a C API function.
347+
if (rootNode instanceof RubyRootNode &&
348+
rootNode.getSourceSection().isAvailable() &&
349+
!rootNode.getSourceSection().getSource().getName().endsWith("cext.rb") &&
350+
!rootNode.getSourceSection().getSource().getName().endsWith("cext_ruby.rb") &&
351+
!getContext().getCoreLibrary().isSend(
352+
RubyArguments.tryGetMethod(frameInstance.getFrame(FrameAccess.READ_ONLY)))) {
353+
return frameInstance.getFrame(FrameAccess.MATERIALIZE).materialize();
354+
}
355+
}
356+
357+
return null;
358+
}));
359+
}
360+
}
361+
326362
@Primitive(name = "proc_special_variables")
327363
public abstract static class GetProcSpecialVariableStorage extends PrimitiveArrayArgumentsNode {
328364

0 commit comments

Comments
 (0)