Skip to content
Permalink
Browse files
[Truffle] Allow filename and line number arguments in Kernel#eval.
These parameters are currently ignored.  The semantics of eval continue to work fine in most cases with the ignored parameters, so I've committed this work in order to avoid issues in code that calls eval with the extra arguments, such as ERB.
  • Loading branch information
nirvdrum committed Dec 29, 2014
1 parent 73aa13c commit 56420a03054ed591ba8ca162a296b63440a90ff4
Showing with 26 additions and 14 deletions.
  1. +24 −8 core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
  2. +2 −6 spec/truffle/tags/core/kernel/eval_tags.txt
@@ -478,7 +478,7 @@ public EqlNode(EqlNode prev) {
}
}

@CoreMethod(names = "eval", isModuleFunction = true, required = 1, optional = 1)
@CoreMethod(names = "eval", isModuleFunction = true, required = 1, optional = 3)
public abstract static class EvalNode extends CoreMethodNode {

@Child protected DispatchHeadNode toStr;
@@ -503,28 +503,44 @@ protected RubyBinding getCallerBinding(VirtualFrame frame) {
}

@Specialization
public Object eval(VirtualFrame frame, RubyString source, UndefinedPlaceholder binding) {
public Object eval(VirtualFrame frame, RubyString source, UndefinedPlaceholder binding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) {
notDesignedForCompilation();

return eval(source, getCallerBinding(frame));
return eval(source, getCallerBinding(frame), filename, lineNumber);
}

@Specialization
public Object eval(RubyString source, RubyBinding binding) {
public Object eval(RubyString source, RubyBinding binding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) {
notDesignedForCompilation();

return getContext().eval(source.getBytes(), binding, this);
}

@Specialization
public Object eval(RubyString source, RubyBinding binding, RubyString filename, UndefinedPlaceholder lineNumber) {
notDesignedForCompilation();

// TODO (nirvdrum Dec. 29, 2014) Do something with the supplied filename.
return getContext().eval(source.getBytes(), binding, this);
}

@Specialization
public Object eval(RubyString source, RubyBinding binding, RubyString filename, int lineNumber) {
notDesignedForCompilation();

// TODO (nirvdrum Dec. 29, 2014) Do something with the supplied filename and lineNumber.
return getContext().eval(source.getBytes(), binding, this);
}

@Specialization(guards = "!isRubyString(arguments[0])")
public Object eval(VirtualFrame frame, RubyBasicObject object, UndefinedPlaceholder binding) {
public Object eval(VirtualFrame frame, RubyBasicObject object, UndefinedPlaceholder binding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) {
notDesignedForCompilation();

return eval(frame, object, getCallerBinding(frame));
return eval(frame, object, getCallerBinding(frame), filename, lineNumber);
}

@Specialization(guards = "!isRubyString(arguments[0])")
public Object eval(VirtualFrame frame, RubyBasicObject object, RubyBinding binding) {
public Object eval(VirtualFrame frame, RubyBasicObject object, RubyBinding binding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) {
notDesignedForCompilation();

Object coerced;
@@ -556,7 +572,7 @@ public Object eval(VirtualFrame frame, RubyBasicObject object, RubyBinding bindi
}

@Specialization(guards = "!isRubyBinding(arguments[1])")
public Object eval(RubyBasicObject source, RubyBasicObject badBinding) {
public Object eval(RubyBasicObject source, RubyBasicObject badBinding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) {
throw new RaiseException(
getContext().getCoreLibrary().typeError(
String.format("wrong argument type %s (expected binding)",
@@ -2,12 +2,8 @@ fails:Kernel#eval evaluates within the scope of the eval
fails:Kernel#eval evaluates such that consts are scoped to the class of the eval
fails:Kernel#eval allows a binding to be captured inside an eval
fails:Kernel#eval uses the same scope for local variables when given the same binding
fails:Kernel#eval includes file and line information in syntax error
fails:Kernel#eval sets constants at the toplevel from inside a block
fails:Kernel#eval uses the filename of the binding if none is provided
fails:Kernel#eval does not alter the value of __FILE__ in the binding
passes:Kernel#eval uses the filename of the binding if none is provided
fails:Kernel#eval uses the receiver as self inside the eval
fails:Kernel#eval returns from the scope calling #eval when evaluating 'return'
fails:Kernel#eval unwinds through a Proc-style closure and returns from a lambda-style closure in the closure chain
fails:Kernel#eval does not share locals across eval scopes
fails:Kernel#eval raises a LocalJumpError if there is no lambda-style closure in the chain
fails:Kernel#eval unwinds through a Proc-style closure and returns from a lambda-style closure in the closure chain

0 comments on commit 56420a0

Please sign in to comment.