Skip to content

Commit ef85f9e

Browse files
committed
Add storage for special variables and primitive to access them.
1 parent e7a7f15 commit ef85f9e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+882
-326
lines changed

lib/truffle/stringio.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ def gets(sep=$/, limit=Undefined)
315315

316316
# Truffle: $_ is thread and frame local, so we use a primitive to
317317
# set it in the caller's frame.
318-
Primitive.frame_local_variable_set(:$_, getline(false, sep, limit), Primitive.caller_binding)
318+
Primitive.io_last_line_set(Primitive.caller_special_variable, getline(false, sep, limit))
319319
end
320320

321321
def isatty
@@ -346,7 +346,7 @@ def pos=(pos)
346346

347347
def print(*args)
348348
check_writable
349-
args << Primitive.frame_local_variable_get(:$_, Primitive.caller_binding) if args.empty?
349+
args << Primitive.io_last_line_get(Primitive.caller_special_variable) if args.empty?
350350
write((args << $\).flatten.join)
351351
nil
352352
end
@@ -449,7 +449,7 @@ def readline(sep=$/, limit=Undefined)
449449
check_readable
450450
raise EOFError, 'end of file reached' if eof?
451451

452-
Primitive.frame_local_variable_set(:$_, getline(true, sep, limit), Primitive.caller_binding)
452+
Primitive.io_last_line_set(Primitive.caller_special_variable, getline(true, sep, limit))
453453
end
454454

455455
def readlines(sep=$/, limit=Undefined)

lib/truffle/truffle/cext.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,8 +1700,7 @@ def rb_tr_writable(mode)
17001700
end
17011701

17021702
def rb_backref_get
1703-
Primitive.frame_local_variable_get(:$~,
1704-
Truffle::ThreadOperations.ruby_caller([Truffle::CExt, Truffle::Interop.singleton_class]))
1703+
Primitive.regexp_last_match_get(Truffle::ThreadOperations.ruby_caller_special_variable([Truffle::CExt, Truffle::Interop.singleton_class]))
17051704
end
17061705

17071706
def rb_gv_set(name, value)
@@ -1719,7 +1718,7 @@ def rb_gv_get(name)
17191718

17201719
def rb_reg_match(re, str)
17211720
result = str ? Truffle::RegexpOperations.match(re, str, 0) : nil
1722-
Primitive.frame_local_variable_set(:$~, result, Truffle::ThreadOperations.ruby_caller([Truffle::CExt, Truffle::Interop.singleton_class]))
1721+
Primitive.regexp_last_match_set(Truffle::ThreadOperations.ruby_caller_special_variable([Truffle::CExt, Truffle::Interop.singleton_class]), result)
17231722

17241723
result.begin(0) if result
17251724
end

src/main/java/org/truffleruby/Layouts.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import com.oracle.truffle.api.object.HiddenKey;
1313

14+
import org.truffleruby.parser.TranslatorEnvironment;
15+
1416
public abstract class Layouts {
1517

1618
// Standard identifiers
@@ -23,4 +25,8 @@ public abstract class Layouts {
2325
public static final HiddenKey MARKED_OBJECTS_IDENTIFIER = new HiddenKey("marked_objects"); // Object[]
2426
public static final HiddenKey VALUE_WRAPPER_IDENTIFIER = new HiddenKey("value_wrapper"); // ValueWrapper
2527

28+
// Frame slot name for special variable storage.
29+
30+
public static final String SPECIAL_VARIABLLE_STORAGE = TranslatorEnvironment.TEMP_PREFIX + "$~_";
31+
2632
}

src/main/java/org/truffleruby/RubyContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ public Object send(Object object, String methodName, Object... arguments) {
424424

425425
return IndirectCallNode.getUncached().call(
426426
method.getCallTarget(),
427-
RubyArguments.pack(null, null, method, null, object, null, arguments));
427+
RubyArguments.pack(null, null, null, method, null, object, null, arguments));
428428
}
429429

430430
@TruffleBoundary

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import org.jcodings.specific.USASCIIEncoding;
2727
import org.jcodings.transcode.EConvFlags;
28+
import org.truffleruby.Layouts;
2829
import org.truffleruby.RubyContext;
2930
import org.truffleruby.RubyLanguage;
3031
import org.truffleruby.SuppressFBWarnings;
@@ -77,6 +78,7 @@
7778
import com.oracle.truffle.api.Truffle;
7879
import com.oracle.truffle.api.TruffleOptions;
7980
import com.oracle.truffle.api.frame.FrameDescriptor;
81+
import com.oracle.truffle.api.frame.FrameSlot;
8082
import com.oracle.truffle.api.object.DynamicObjectLibrary;
8183
import com.oracle.truffle.api.source.Source;
8284
import com.oracle.truffle.api.source.SourceSection;
@@ -224,6 +226,11 @@ public class CoreLibrary {
224226
public final GlobalVariables globalVariables;
225227

226228
public final FrameDescriptor emptyDescriptor;
229+
/* Some things (such as procs created from symbols) require a declaration frame, and this should include a slot for
230+
* special variable storage. This frame descriptor should be used for those frames to provide a constant frame shape
231+
* in those cases. */
232+
public final FrameDescriptor emptyDeclarationDescriptor;
233+
public final FrameSlot emptyDeclarationSpecialVariableSlot;
227234

228235
@CompilationFinal private RubyClass eagainWaitReadable;
229236
@CompilationFinal private RubyClass eagainWaitWritable;
@@ -585,6 +592,9 @@ public CoreLibrary(RubyContext context) {
585592

586593
mainObject = new RubyBasicObject(objectClass, language.basicObjectShape);
587594
emptyDescriptor = new FrameDescriptor(Nil.INSTANCE);
595+
emptyDeclarationDescriptor = new FrameDescriptor(Nil.INSTANCE);
596+
emptyDeclarationSpecialVariableSlot = emptyDeclarationDescriptor
597+
.addFrameSlot(Layouts.SPECIAL_VARIABLLE_STORAGE);
588598
argv = new RubyArray(arrayClass, RubyLanguage.arrayShape, ArrayStoreLibrary.INITIAL_STORE, 0);
589599

590600
globalVariables = new GlobalVariables();

src/main/java/org/truffleruby/core/binding/BindingNodes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public static MaterializedFrame newFrame(MaterializedFrame parent, FrameDescript
106106
RubyArguments.pack(
107107
parent,
108108
null,
109+
null,
109110
RubyArguments.getMethod(parent),
110111
RubyArguments.getDeclarationContext(parent),
111112
null,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,7 @@ private Object eval(Object target, RootNodeWrapper rootNode, RootCallTarget call
786786
return callNode.call(RubyArguments.pack(
787787
parentFrame,
788788
null,
789+
null,
789790
method,
790791
null,
791792
target,

0 commit comments

Comments
 (0)