Skip to content

Commit

Permalink
[Truffle] Binding#{local_variable_get/set} cast name param
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Fish committed Sep 26, 2016
1 parent daa6c8d commit c0c7080
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 44 deletions.
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/binding/local_variable_set_tags.txt

This file was deleted.

Expand Up @@ -177,52 +177,54 @@ protected boolean isLastLine(String name) {

@ImportStatic(BindingNodes.class)
@CoreMethod(names = "local_variable_get", required = 1)
public abstract static class LocalVariableGetNode extends CoreMethodArrayArgumentsNode {

private final DynamicObject dollarUnderscore;
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "binding"),
@NodeChild(type = RubyNode.class, value = "name")
})
public abstract static class LocalVariableGetNode extends CoreMethodNode {

public LocalVariableGetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
dollarUnderscore = getSymbol("$_");
@CreateCast("name")
public RubyNode coerceToString(RubyNode name) {
return NameToJavaStringNodeGen.create(name);
}


@Specialization(guards = {
"isRubySymbol(symbol)",
"symbol == cachedSymbol",
"!isLastLine(cachedSymbol)",
"name == cachedName",
"!isLastLine(cachedName)",
"compatibleFrames(binding, cachedBinding)",
"cachedFrameSlot != null"
},
limit = "getCacheLimit()")
public Object localVariableGetCached(DynamicObject binding, DynamicObject symbol,
@Cached("symbol") DynamicObject cachedSymbol,
public Object localVariableGetCached(DynamicObject binding, String name,
@Cached("name") String cachedName,
@Cached("binding") DynamicObject cachedBinding,
@Cached("findFrameSlotOrNull(binding, symbol)") FrameSlotAndDepth cachedFrameSlot,
@Cached("findFrameSlotOrNull(binding, name)") FrameSlotAndDepth cachedFrameSlot,
@Cached("createReadNode(cachedFrameSlot)") ReadFrameSlotNode readLocalVariableNode) {
final MaterializedFrame frame = RubyArguments.getDeclarationFrame(Layouts.BINDING.getFrame(binding), cachedFrameSlot.depth);
return readLocalVariableNode.executeRead(frame);
}

@TruffleBoundary
@Specialization(guards = { "isRubySymbol(symbol)", "!isLastLine(symbol)" })
public Object localVariableGetUncached(DynamicObject binding, DynamicObject symbol) {
final FrameSlotAndDepth frameSlot = findFrameSlotOrNull(binding, symbol);
@Specialization(guards = "!isLastLine(name)" )
public Object localVariableGetUncached(DynamicObject binding, String name) {
final FrameSlotAndDepth frameSlot = findFrameSlotOrNull(binding, name);
if (frameSlot == null) {
throw new RaiseException(coreExceptions().nameErrorLocalVariableNotDefined(Layouts.SYMBOL.getString(symbol), binding, this));
throw new RaiseException(coreExceptions().nameErrorLocalVariableNotDefined(name, binding, this));
} else {
final MaterializedFrame frame = RubyArguments.getDeclarationFrame(Layouts.BINDING.getFrame(binding), frameSlot.depth);
return frame.getValue(frameSlot.slot);
}
}

@TruffleBoundary
@Specialization(guards = {"isRubySymbol(symbol)", "isLastLine(symbol)"})
public Object localVariableGetLastLine(DynamicObject binding, DynamicObject symbol) {
@Specialization(guards = "isLastLine(name)")
public Object localVariableGetLastLine(DynamicObject binding, String name) {
final MaterializedFrame frame = Layouts.BINDING.getFrame(binding);
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(Layouts.SYMBOL.getString(symbol));
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(name);

if (frameSlot == null) {
throw new RaiseException(coreExceptions().nameErrorLocalVariableNotDefined(Layouts.SYMBOL.getString(symbol), binding, this));
throw new RaiseException(coreExceptions().nameErrorLocalVariableNotDefined(name, binding, this));
}

final Object value = frame.getValue(frameSlot);
Expand Down Expand Up @@ -263,8 +265,8 @@ protected ReadFrameSlotNode createReadNode(FrameSlotAndDepth frameSlot) {
}
}

protected boolean isLastLine(DynamicObject symbol) {
return symbol == dollarUnderscore;
protected boolean isLastLine(String name) {
return "$_".equals(name);
}

protected int getCacheLimit() {
Expand All @@ -275,52 +277,58 @@ protected int getCacheLimit() {

@ImportStatic(BindingNodes.class)
@CoreMethod(names = "local_variable_set", required = 2)
public abstract static class LocalVariableSetNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "binding"),
@NodeChild(type = RubyNode.class, value = "name"),
@NodeChild(type = RubyNode.class, value = "value")
})
public abstract static class LocalVariableSetNode extends CoreMethodNode {

private final DynamicObject dollarUnderscore;
@CreateCast("name")
public RubyNode coerceToString(RubyNode name) {
return NameToJavaStringNodeGen.create(name);
}

public LocalVariableSetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
dollarUnderscore = getSymbol("$_");
}

@Specialization(guards = {
"isRubySymbol(symbol)",
"!isLastLine(symbol)",
"!isLastLine(name)",
"getFrameDescriptor(binding) == cachedFrameDescriptor",
"symbol == cachedSymbol"
"name == cachedName"
}, limit = "getCacheLimit()")
public Object localVariableSetCached(DynamicObject binding, DynamicObject symbol, Object value,
@Cached("symbol") DynamicObject cachedSymbol,
public Object localVariableSetCached(DynamicObject binding, String name, Object value,
@Cached("name") String cachedName,
@Cached("getFrameDescriptor(binding)") FrameDescriptor cachedFrameDescriptor,
@Cached("findFrameSlot(binding, symbol)") FrameSlotAndDepth cachedFrameSlot,
@Cached("findFrameSlot(binding, name)") FrameSlotAndDepth cachedFrameSlot,
@Cached("createWriteNode(cachedFrameSlot)") WriteFrameSlotNode writeLocalVariableNode) {
final MaterializedFrame frame = RubyArguments.getDeclarationFrame(Layouts.BINDING.getFrame(binding), cachedFrameSlot.depth);
return writeLocalVariableNode.executeWrite(frame, value);
}

@TruffleBoundary
@Specialization(guards = { "isRubySymbol(symbol)", "!isLastLine(symbol)" })
public Object localVariableSetUncached(DynamicObject binding, DynamicObject symbol, Object value) {
final FrameSlotAndDepth frameSlot = findFrameSlot(binding, symbol);
@Specialization(guards = "!isLastLine(name)" )
public Object localVariableSetUncached(DynamicObject binding, String name, Object value) {
final FrameSlotAndDepth frameSlot = findFrameSlot(binding, name);
final MaterializedFrame frame = RubyArguments.getDeclarationFrame(Layouts.BINDING.getFrame(binding), frameSlot.depth);
frame.setObject(frameSlot.slot, value);
return value;
}

@TruffleBoundary
@Specialization(guards = {"isRubySymbol(symbol)", "isLastLine(symbol)"})
public Object localVariableSetLastLine(DynamicObject binding, DynamicObject symbol, Object value) {
@Specialization(guards = "isLastLine(name)")
public Object localVariableSetLastLine(DynamicObject binding, String name, Object value) {
final MaterializedFrame frame = Layouts.BINDING.getFrame(binding);
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(Layouts.SYMBOL.getString(symbol));
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(name);
frame.setObject(frameSlot, ThreadLocalObject.wrap(getContext(), value));
return value;
}

protected FrameSlotAndDepth findFrameSlot(DynamicObject binding, DynamicObject symbol) {
final FrameSlotAndDepth frameSlot = BindingNodes.findFrameSlotOrNull(binding, symbol);
protected FrameSlotAndDepth findFrameSlot(DynamicObject binding, String name) {
final FrameSlotAndDepth frameSlot = BindingNodes.findFrameSlotOrNull(binding, name);
if (frameSlot == null) {
final FrameSlot newSlot = Layouts.BINDING.getFrame(binding).getFrameDescriptor().addFrameSlot(Layouts.SYMBOL.getString(symbol));
final FrameSlot newSlot = Layouts.BINDING.getFrame(binding).getFrameDescriptor().addFrameSlot(name);
return new FrameSlotAndDepth(newSlot, 0);
} else {
return frameSlot;
Expand All @@ -331,8 +339,8 @@ protected WriteFrameSlotNode createWriteNode(FrameSlotAndDepth frameSlot) {
return WriteFrameSlotNodeGen.create(frameSlot.slot);
}

protected boolean isLastLine(DynamicObject symbol) {
return symbol == dollarUnderscore;
protected boolean isLastLine(String name) {
return "$_".equals("name");
}

protected int getCacheLimit() {
Expand Down

0 comments on commit c0c7080

Please sign in to comment.