46
46
import org .truffleruby .core .array .RubyArray ;
47
47
import org .truffleruby .core .cast .BooleanCastWithDefaultNode ;
48
48
import org .truffleruby .core .cast .NameToJavaStringNode ;
49
+ import org .truffleruby .core .cast .ToIntNode ;
49
50
import org .truffleruby .core .cast .ToPathNodeGen ;
50
51
import org .truffleruby .core .cast .ToStrNode ;
51
52
import org .truffleruby .core .cast .ToStringOrSymbolNodeGen ;
@@ -662,89 +663,78 @@ protected Object isAutoload(RubyModule module, String name, boolean inherit) {
662
663
}
663
664
}
664
665
665
- @ CoreMethod (names = { "class_eval" , "module_eval" }, optional = 3 , lowerFixnum = 3 , needsBlock = true )
666
- public abstract static class ClassEvalNode extends CoreMethodArrayArgumentsNode {
666
+ @ GenerateUncached
667
+ @ CoreMethod (names = { "class_eval" , "module_eval" }, optional = 3 , needsBlock = true , alwaysInlined = true )
668
+ public abstract static class ClassEvalNode extends AlwaysInlinedMethodNode {
667
669
668
- @ Child private ReadCallerFrameNode readCallerFrameNode = ReadCallerFrameNode .create ();
670
+ @ Specialization (guards = "isBlockProvided(rubyArgs)" )
671
+ protected Object evalWithBlock (Frame callerFrame , RubyModule self , Object [] rubyArgs , RootCallTarget target ,
672
+ @ Cached BranchProfile errorProfile ,
673
+ @ Cached (allowUncached = true ) ClassExecNode classExecNode ) {
674
+ final int count = RubyArguments .getPositionalArgumentsCount (rubyArgs , false );
669
675
670
- @ Specialization (guards = "libCode.isRubyString(code)" , limit = "1" )
671
- protected Object classEval (
672
- VirtualFrame frame , RubyModule module , Object code , NotProvided file , NotProvided line , Nil block ,
673
- @ Cached IndirectCallNode callNode ,
674
- @ Cached RubyStringLibrary libCode ) {
675
- return classEvalSource (frame , module , code , "(eval)" , callNode );
676
- }
676
+ if (count > 0 ) {
677
+ errorProfile .enter ();
678
+ throw new RaiseException (getContext (), coreExceptions ().argumentError (count , 0 , this ));
679
+ }
677
680
678
- @ Specialization (guards = { "libCode.isRubyString(code)" , "libFile.isRubyString(file)" }, limit = "1" )
679
- protected Object classEval (
680
- VirtualFrame frame , RubyModule module , Object code , Object file , NotProvided line , Nil block ,
681
- @ Cached IndirectCallNode callNode ,
682
- @ Cached RubyStringLibrary libCode ,
683
- @ Cached RubyStringLibrary libFile ,
684
- @ Cached ToJavaStringNode toJavaStringNode ) {
685
- return classEvalSource (frame , module , code , toJavaStringNode .executeToJavaString (file ), callNode );
681
+ final Object block = RubyArguments .getBlock (rubyArgs );
682
+ return classExecNode .classExec (EmptyArgumentsDescriptor .INSTANCE , self , new Object []{ self },
683
+ (RubyProc ) block );
686
684
}
687
685
688
- @ Specialization (guards = { "libCode.isRubyString(code)" , "wasProvided(file)" }, limit = "1" )
689
- protected Object classEval (VirtualFrame frame , RubyModule module , Object code , Object file , int line , Nil block ,
690
- @ Cached IndirectCallNode callNode ,
691
- @ Cached RubyStringLibrary libCode ,
692
- @ Cached RubyStringLibrary libFile ,
693
- @ Cached ToJavaStringNode toJavaStringNode ) {
694
- final CodeLoader .DeferredCall deferredCall = classEvalSource (
695
- frame ,
696
- module ,
697
- code ,
698
- toJavaStringNode .executeToJavaString (file ),
699
- line );
700
- return deferredCall .call (callNode );
701
- }
686
+ @ Specialization (guards = "!isBlockProvided(rubyArgs)" )
687
+ protected Object evalWithString (Frame callerFrame , RubyModule self , Object [] rubyArgs , RootCallTarget target ,
688
+ @ Cached BranchProfile errorProfile ,
689
+ @ Cached ToJavaStringNode toJavaStringNode ,
690
+ @ Cached ToStrNode toStrNode ,
691
+ @ Cached ToIntNode toIntNode ,
692
+ @ Cached IndirectCallNode callNode ) {
693
+ final Object sourceCode ;
694
+ String fileName = coreStrings ().EVAL_FILENAME_STRING .toString ();
695
+ int line = 1 ;
702
696
703
- @ Specialization (guards = "wasProvided(code)" )
704
- protected Object classEval (
705
- VirtualFrame frame , RubyModule module , Object code , NotProvided file , NotProvided line , Nil block ,
706
- @ Cached IndirectCallNode callNode ,
707
- @ Cached ToStrNode toStrNode ) {
708
- return classEvalSource (frame , module , toStrNode .execute (code ), "(eval)" , callNode );
709
- }
697
+ int count = RubyArguments .getPositionalArgumentsCount (rubyArgs , false );
710
698
711
- @ Specialization (guards = { "libCode.isRubyString(code)" , "wasProvided(file)" }, limit = "1" )
712
- protected Object classEval (
713
- VirtualFrame frame , RubyModule module , Object code , Object file , NotProvided line , Nil block ,
714
- @ Cached RubyStringLibrary stringLibrary ,
715
- @ Cached ToJavaStringNode toJavaStringNode ,
716
- @ Cached IndirectCallNode callNode ,
717
- @ Cached RubyStringLibrary libCode ,
718
- @ Cached ToStrNode toStrNode ) {
719
- final String javaString = toJavaStringNode .executeToJavaString (toStrNode .execute (file ));
720
- return classEvalSource (frame , module , code , javaString , callNode );
721
- }
699
+ if (count == 0 ) {
700
+ errorProfile .enter ();
701
+ throw new RaiseException (getContext (), coreExceptions ().argumentError (0 , 1 , 2 , this ));
702
+ }
722
703
723
- private Object classEvalSource (VirtualFrame frame , RubyModule module , Object code , String file ,
724
- @ Cached IndirectCallNode callNode ) {
725
- final CodeLoader .DeferredCall deferredCall = classEvalSource (frame , module , code , file , 1 );
726
- return deferredCall .call (callNode );
727
- }
704
+ sourceCode = toStrNode .execute (RubyArguments .getArgument (rubyArgs , 0 ));
728
705
729
- private CodeLoader .DeferredCall classEvalSource (VirtualFrame frame , RubyModule module ,
730
- Object rubySource , String file , int line ) {
706
+ if (count >= 2 ) {
707
+ fileName = toJavaStringNode
708
+ .executeToJavaString (toStrNode .execute (RubyArguments .getArgument (rubyArgs , 1 )));
709
+ }
731
710
732
- final MaterializedFrame callerFrame = readCallerFrameNode .execute (frame );
711
+ if (count >= 3 ) {
712
+ line = toIntNode .execute (RubyArguments .getArgument (rubyArgs , 2 ));
713
+ }
733
714
734
- return classEvalSourceInternal (module , rubySource , file , line , callerFrame );
715
+ needCallerFrame (callerFrame , target );
716
+ return classEvalSource (
717
+ callerFrame .materialize (),
718
+ self ,
719
+ sourceCode ,
720
+ fileName ,
721
+ line ,
722
+ callNode );
735
723
}
736
724
737
725
@ TruffleBoundary
738
- private CodeLoader .DeferredCall classEvalSourceInternal (RubyModule module , Object rubySource ,
739
- String file , int line , MaterializedFrame callerFrame ) {
726
+ private Object classEvalSource (MaterializedFrame callerFrame , RubyModule module , Object sourceCode , String file ,
727
+ int line ,
728
+ IndirectCallNode callNode ) {
740
729
final RubySource source = EvalLoader .createEvalSource (
741
730
getContext (),
742
- RubyStringLibrary .getUncached ().getTString (rubySource ),
743
- RubyStringLibrary .getUncached ().getEncoding (rubySource ),
731
+ RubyStringLibrary .getUncached ().getTString (sourceCode ),
732
+ RubyStringLibrary .getUncached ().getEncoding (sourceCode ),
744
733
"class/module_eval" ,
745
734
file ,
746
735
line ,
747
736
this );
737
+
748
738
final LexicalScope lexicalScope = new LexicalScope (
749
739
RubyArguments .getMethod (callerFrame ).getLexicalScope (),
750
740
module );
@@ -756,7 +746,7 @@ private CodeLoader.DeferredCall classEvalSourceInternal(RubyModule module, Objec
756
746
lexicalScope ,
757
747
this );
758
748
759
- return getContext ().getCodeLoader ().prepareExecute (
749
+ final CodeLoader . DeferredCall deferredCall = getContext ().getCodeLoader ().prepareExecute (
760
750
callTarget ,
761
751
ParserContext .MODULE ,
762
752
new DeclarationContext (
@@ -766,23 +756,8 @@ private CodeLoader.DeferredCall classEvalSourceInternal(RubyModule module, Objec
766
756
callerFrame ,
767
757
module ,
768
758
lexicalScope );
769
- }
770
-
771
- @ Specialization
772
- protected Object classEval (
773
- RubyModule self , NotProvided code , NotProvided file , NotProvided line , RubyProc block ,
774
- @ Cached ClassExecNode classExecNode ) {
775
- return classExecNode .classExec (EmptyArgumentsDescriptor .INSTANCE , self , new Object []{ self }, block );
776
- }
777
759
778
- @ Specialization
779
- protected Object classEval (RubyModule self , NotProvided code , NotProvided file , NotProvided line , Nil block ) {
780
- throw new RaiseException (getContext (), coreExceptions ().argumentError (0 , 1 , 2 , this ));
781
- }
782
-
783
- @ Specialization (guards = "wasProvided(code)" )
784
- protected Object classEval (RubyModule self , Object code , NotProvided file , NotProvided line , RubyProc block ) {
785
- throw new RaiseException (getContext (), coreExceptions ().argumentError (1 , 0 , this ));
760
+ return deferredCall .call (callNode );
786
761
}
787
762
788
763
}
0 commit comments