99 */
1010package org .jruby .truffle .nodes .core ;
1111
12+ import com .oracle .truffle .api .Truffle ;
1213import com .oracle .truffle .api .dsl .Specialization ;
14+ import com .oracle .truffle .api .frame .FrameInstance ;
1315import com .oracle .truffle .api .frame .FrameSlot ;
1416import com .oracle .truffle .api .frame .MaterializedFrame ;
1517import com .oracle .truffle .api .source .SourceSection ;
18+ import org .jruby .Ruby ;
1619import org .jruby .runtime .Visibility ;
1720import org .jruby .truffle .nodes .globals .GetFromThreadLocalNode ;
1821import org .jruby .truffle .nodes .globals .WrapInThreadLocalNode ;
1922import org .jruby .truffle .runtime .RubyArguments ;
2023import org .jruby .truffle .runtime .RubyContext ;
21- import org .jruby .truffle .runtime .core .RubyBinding ;
22- import org .jruby .truffle .runtime .core .RubyString ;
23- import org .jruby .truffle .runtime .core .RubySymbol ;
24+ import org .jruby .truffle .runtime .core .*;
25+ import org .jruby .truffle .runtime .methods .InternalMethod ;
2426
2527@ CoreClass (name = "Binding" )
2628public abstract class BindingNodes {
@@ -44,7 +46,16 @@ public Object initializeCopy(RubyBinding self, RubyBinding from) {
4446 return self ;
4547 }
4648
47- self .initialize (from .getSelf (), from .getFrame ());
49+ final Object [] arguments = from .getFrame ().getArguments ();
50+ final InternalMethod method = RubyArguments .getMethod (arguments );
51+ final Object boundSelf = RubyArguments .getSelf (arguments );
52+ final RubyProc boundBlock = RubyArguments .getBlock (arguments );
53+ final Object [] userArguments = RubyArguments .extractUserArguments (arguments );
54+
55+ final Object [] copiedArguments = RubyArguments .pack (method , from .getFrame (), boundSelf , boundBlock , userArguments );
56+ final MaterializedFrame copiedFrame = Truffle .getRuntime ().createMaterializedFrame (copiedArguments );
57+
58+ self .initialize (from .getSelf (), copiedFrame );
4859
4960 return self ;
5061 }
@@ -101,22 +112,53 @@ public Object localVariableSetNode(RubyBinding binding, RubySymbol symbol, Objec
101112
102113 MaterializedFrame frame = binding .getFrame ();
103114
104- while (true ) {
115+ while (frame != null ) {
105116 final FrameSlot frameSlot = frame .getFrameDescriptor ().findFrameSlot (symbol .toString ());
106117
107118 if (frameSlot != null ) {
108119 frame .setObject (frameSlot , value );
109- break ;
120+ return value ;
110121 }
111122
112123 frame = RubyArguments .getDeclarationFrame (frame .getArguments ());
124+ }
125+
126+ final FrameSlot newFrameSlot = binding .getFrame ().getFrameDescriptor ().addFrameSlot (symbol .toString ());
127+ binding .getFrame ().setObject (newFrameSlot , value );
128+ return value ;
129+ }
130+ }
131+
132+ @ CoreMethod (names = "local_variables" )
133+ public abstract static class LocalVariablesNode extends CoreMethodNode {
134+
135+ public LocalVariablesNode (RubyContext context , SourceSection sourceSection ) {
136+ super (context , sourceSection );
137+ }
113138
114- if (frame == null ) {
115- throw new UnsupportedOperationException ();
139+ public LocalVariablesNode (LocalVariablesNode prev ) {
140+ super (prev );
141+ }
142+
143+ @ Specialization
144+ public RubyArray localVariables (RubyBinding binding ) {
145+ notDesignedForCompilation ();
146+
147+ final RubyArray array = new RubyArray (getContext ().getCoreLibrary ().getArrayClass ());
148+
149+ MaterializedFrame frame = binding .getFrame ();
150+
151+ while (frame != null ) {
152+ for (Object name : frame .getFrameDescriptor ().getIdentifiers ()) {
153+ if (name instanceof String ) {
154+ array .slowPush (getContext ().newSymbol ((String ) name ));
155+ }
116156 }
157+
158+ frame = RubyArguments .getDeclarationFrame (frame .getArguments ());
117159 }
118160
119- return value ;
161+ return array ;
120162 }
121163 }
122164
0 commit comments