|
12 | 12 | import com.oracle.truffle.api.CompilerDirectives;
|
13 | 13 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
14 | 14 | import com.oracle.truffle.api.Truffle;
|
| 15 | +import com.oracle.truffle.api.dsl.CreateCast; |
| 16 | +import com.oracle.truffle.api.dsl.NodeChild; |
| 17 | +import com.oracle.truffle.api.dsl.NodeChildren; |
15 | 18 | import com.oracle.truffle.api.dsl.Specialization;
|
16 | 19 | import com.oracle.truffle.api.frame.*;
|
17 | 20 | import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
|
25 | 28 | import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory;
|
26 | 29 | import org.jruby.truffle.nodes.cast.NumericToFloatNode;
|
27 | 30 | import org.jruby.truffle.nodes.cast.NumericToFloatNodeFactory;
|
| 31 | +import org.jruby.truffle.nodes.coerce.ToStrNode; |
| 32 | +import org.jruby.truffle.nodes.coerce.ToStrNodeFactory; |
28 | 33 | import org.jruby.truffle.nodes.control.WhileNode;
|
29 | 34 | import org.jruby.truffle.nodes.core.KernelNodesFactory.SameOrEqualNodeFactory;
|
30 | 35 | import org.jruby.truffle.nodes.dispatch.*;
|
@@ -513,19 +518,27 @@ public Object dup(VirtualFrame frame, RubyBasicObject self) {
|
513 | 518 | }
|
514 | 519 |
|
515 | 520 | @CoreMethod(names = "eval", isModuleFunction = true, required = 1, optional = 3)
|
516 |
| - public abstract static class EvalNode extends CoreMethodNode { |
| 521 | + @NodeChildren({ |
| 522 | + @NodeChild(value = "source", type = RubyNode.class), |
| 523 | + @NodeChild(value = "binding", type = RubyNode.class), |
| 524 | + @NodeChild(value = "filename", type = RubyNode.class), |
| 525 | + @NodeChild(value = "lineNumber", type = RubyNode.class) |
| 526 | + }) |
| 527 | + public abstract static class EvalNode extends RubyNode { |
517 | 528 |
|
518 | 529 | @Child private CallDispatchHeadNode toStr;
|
519 | 530 | @Child private BindingNode bindingNode;
|
520 | 531 |
|
521 | 532 | public EvalNode(RubyContext context, SourceSection sourceSection) {
|
522 | 533 | super(context, sourceSection);
|
523 |
| - toStr = DispatchHeadNodeFactory.createMethodCall(context); |
524 | 534 | }
|
525 | 535 |
|
526 | 536 | public EvalNode(EvalNode prev) {
|
527 | 537 | super(prev);
|
528 |
| - toStr = prev.toStr; |
| 538 | + } |
| 539 | + |
| 540 | + @CreateCast("source") public RubyNode coerceSourceToString(RubyNode source) { |
| 541 | + return ToStrNodeFactory.create(getContext(), getSourceSection(), source); |
529 | 542 | }
|
530 | 543 |
|
531 | 544 | protected RubyBinding getCallerBinding(VirtualFrame frame) {
|
@@ -574,57 +587,14 @@ public Object eval(RubyString source, RubyBinding binding, RubyString filename,
|
574 | 587 | return getContext().eval(source.getBytes(), binding, false, this);
|
575 | 588 | }
|
576 | 589 |
|
577 |
| - @Specialization(guards = "!isRubyString(arguments[0])") |
578 |
| - public Object eval(VirtualFrame frame, RubyBasicObject object, UndefinedPlaceholder binding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) { |
579 |
| - notDesignedForCompilation(); |
580 |
| - |
581 |
| - return evalCoerced(frame, object, getCallerBinding(frame), true, filename, lineNumber); |
582 |
| - } |
583 |
| - |
584 |
| - @Specialization(guards = "!isRubyString(arguments[0])") |
585 |
| - public Object eval(VirtualFrame frame, RubyBasicObject object, RubyBinding binding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) { |
586 |
| - notDesignedForCompilation(); |
587 |
| - |
588 |
| - return evalCoerced(frame, object, binding, false, filename, lineNumber); |
589 |
| - } |
590 |
| - |
591 |
| - @Specialization(guards = "!isRubyBinding(arguments[1])") |
592 |
| - public Object eval(RubyBasicObject source, RubyBasicObject badBinding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) { |
| 590 | + @Specialization(guards = "!isRubyBinding(binding)") |
| 591 | + public Object eval(RubyString source, RubyBasicObject badBinding, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) { |
593 | 592 | throw new RaiseException(
|
594 | 593 | getContext().getCoreLibrary().typeError(
|
595 | 594 | String.format("wrong argument type %s (expected binding)",
|
596 | 595 | badBinding.getLogicalClass().getName()),
|
597 | 596 | this));
|
598 | 597 | }
|
599 |
| - |
600 |
| - private Object evalCoerced(VirtualFrame frame, RubyBasicObject object, RubyBinding binding, boolean ownScopeForAssignments, UndefinedPlaceholder filename, UndefinedPlaceholder lineNumber) { |
601 |
| - Object coerced; |
602 |
| - |
603 |
| - try { |
604 |
| - coerced = toStr.call(frame, object, "to_str", null); |
605 |
| - } catch (RaiseException e) { |
606 |
| - if (e.getRubyException().getLogicalClass() == getContext().getCoreLibrary().getNoMethodErrorClass()) { |
607 |
| - throw new RaiseException( |
608 |
| - getContext().getCoreLibrary().typeError( |
609 |
| - String.format("no implicit conversion of %s into String", object.getLogicalClass().getName()), |
610 |
| - this)); |
611 |
| - } else { |
612 |
| - throw e; |
613 |
| - } |
614 |
| - } |
615 |
| - |
616 |
| - if (coerced instanceof RubyString) { |
617 |
| - return getContext().eval(((RubyString) coerced).getBytes(), binding, ownScopeForAssignments, this); |
618 |
| - } else { |
619 |
| - throw new RaiseException( |
620 |
| - getContext().getCoreLibrary().typeError( |
621 |
| - String.format("can't convert %s to String (%s#to_str gives %s)", |
622 |
| - object.getLogicalClass().getName(), |
623 |
| - object.getLogicalClass().getName(), |
624 |
| - getContext().getCoreLibrary().getLogicalClass(coerced).getName()), |
625 |
| - this)); |
626 |
| - } |
627 |
| - } |
628 | 598 | }
|
629 | 599 |
|
630 | 600 | @CoreMethod(names = "exec", isModuleFunction = true, required = 1, argumentsAsArray = true)
|
|
0 commit comments