|
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