Skip to content

Commit

Permalink
[Truffle] Fix Binding#local_variable_set to set in the current frame …
Browse files Browse the repository at this point in the history
…and implement #local_variables
  • Loading branch information
chrisseaton committed Feb 10, 2015
1 parent 21576dd commit 10891a0
Showing 1 changed file with 51 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.Ruby;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.globals.GetFromThreadLocalNode;
import org.jruby.truffle.nodes.globals.WrapInThreadLocalNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBinding;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.methods.InternalMethod;

@CoreClass(name = "Binding")
public abstract class BindingNodes {
Expand All @@ -44,7 +46,16 @@ public Object initializeCopy(RubyBinding self, RubyBinding from) {
return self;
}

self.initialize(from.getSelf(), from.getFrame());
final Object[] arguments = from.getFrame().getArguments();
final InternalMethod method = RubyArguments.getMethod(arguments);
final Object boundSelf = RubyArguments.getSelf(arguments);
final RubyProc boundBlock = RubyArguments.getBlock(arguments);
final Object[] userArguments = RubyArguments.extractUserArguments(arguments);

final Object[] copiedArguments = RubyArguments.pack(method, from.getFrame(), boundSelf, boundBlock, userArguments);
final MaterializedFrame copiedFrame = Truffle.getRuntime().createMaterializedFrame(copiedArguments);

self.initialize(from.getSelf(), copiedFrame);

return self;
}
Expand Down Expand Up @@ -101,22 +112,53 @@ public Object localVariableSetNode(RubyBinding binding, RubySymbol symbol, Objec

MaterializedFrame frame = binding.getFrame();

while (true) {
while (frame != null) {
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString());

if (frameSlot != null) {
frame.setObject(frameSlot, value);
break;
return value;
}

frame = RubyArguments.getDeclarationFrame(frame.getArguments());
}

final FrameSlot newFrameSlot = binding.getFrame().getFrameDescriptor().addFrameSlot(symbol.toString());
binding.getFrame().setObject(newFrameSlot, value);
return value;
}
}

@CoreMethod(names = "local_variables")
public abstract static class LocalVariablesNode extends CoreMethodNode {

public LocalVariablesNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

if (frame == null) {
throw new UnsupportedOperationException();
public LocalVariablesNode(LocalVariablesNode prev) {
super(prev);
}

@Specialization
public RubyArray localVariables(RubyBinding binding) {
notDesignedForCompilation();

final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());

MaterializedFrame frame = binding.getFrame();

while (frame != null) {
for (Object name : frame.getFrameDescriptor().getIdentifiers()) {
if (name instanceof String) {
array.slowPush(getContext().newSymbol((String) name));
}
}

frame = RubyArguments.getDeclarationFrame(frame.getArguments());
}

return value;
return array;
}
}

Expand Down

0 comments on commit 10891a0

Please sign in to comment.