15
15
import com .oracle .truffle .api .RootCallTarget ;
16
16
import com .oracle .truffle .api .Truffle ;
17
17
import com .oracle .truffle .api .TruffleLanguage ;
18
- import com .oracle .truffle .api .frame .MaterializedFrame ;
19
18
import com .oracle .truffle .api .frame .VirtualFrame ;
20
19
import com .oracle .truffle .api .nodes .DirectCallNode ;
21
20
import com .oracle .truffle .api .object .DynamicObject ;
22
21
import com .oracle .truffle .api .source .Source ;
22
+ import org .jcodings .specific .UTF8Encoding ;
23
23
import org .truffleruby .Layouts ;
24
24
import org .truffleruby .RubyContext ;
25
25
import org .truffleruby .RubyLanguage ;
26
+ import org .truffleruby .core .rope .Rope ;
27
+ import org .truffleruby .core .string .StringOperations ;
26
28
import org .truffleruby .language .arguments .RubyArguments ;
27
29
import org .truffleruby .language .backtrace .InternalRootNode ;
28
30
import org .truffleruby .language .methods .DeclarationContext ;
@@ -38,19 +40,21 @@ public class RubyParsingRequestNode extends RubyBaseRootNode implements Internal
38
40
39
41
private final TruffleLanguage .ContextReference <RubyContext > contextReference ;
40
42
private final Source source ;
43
+ private final boolean interactive ;
41
44
private final String [] argumentNames ;
42
45
46
+ @ CompilationFinal private Rope sourceRope ;
43
47
@ CompilationFinal private RubyContext cachedContext ;
44
48
@ CompilationFinal private DynamicObject mainObject ;
45
49
@ CompilationFinal private InternalMethod method ;
46
- @ CompilationFinal private MaterializedFrame declarationFrame ;
47
50
48
51
@ Child private DirectCallNode callNode ;
49
52
50
53
public RubyParsingRequestNode (RubyLanguage language , Source source , String [] argumentNames ) {
51
54
super (language , null , null );
52
- contextReference = language .getContextReference ();
55
+ this . contextReference = language .getContextReference ();
53
56
this .source = source ;
57
+ this .interactive = source .isInteractive ();
54
58
this .argumentNames = argumentNames ;
55
59
}
56
60
@@ -59,6 +63,19 @@ public Object execute(VirtualFrame frame) {
59
63
printTimeMetric ("before-script" );
60
64
final RubyContext context = contextReference .get ();
61
65
66
+ if (interactive ) {
67
+ if (sourceRope == null ) {
68
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
69
+ sourceRope = StringOperations .encodeRope (source .getCharacters ().toString (), UTF8Encoding .INSTANCE );
70
+ }
71
+
72
+ // Just do Truffle::Boot.INTERACTIVE_BINDING.eval(code) for interactive sources.
73
+ // It's the semantics we want and takes care of caching correctly based on the Binding's FrameDescriptor.
74
+ final Object interactiveBinding = Layouts .MODULE .getFields (context .getCoreLibrary ().getTruffleBootModule ())
75
+ .getConstant ("INTERACTIVE_BINDING" ).getValue ();
76
+ return context .send (interactiveBinding , "eval" , StringOperations .createString (context , sourceRope ));
77
+ }
78
+
62
79
if (cachedContext == null ) {
63
80
CompilerDirectives .transferToInterpreterAndInvalidate ();
64
81
cachedContext = context ;
@@ -69,20 +86,12 @@ public Object execute(VirtualFrame frame) {
69
86
70
87
final TranslatorDriver translator = new TranslatorDriver (context );
71
88
72
- final boolean interactive = source .isInteractive ();
73
-
74
- if (interactive ) {
75
- declarationFrame = Layouts .BINDING .getFrame (
76
- (DynamicObject ) Layouts .MODULE .getFields (context .getCoreLibrary ().getTruffleBootModule ())
77
- .getConstant ("INTERACTIVE_BINDING" ).getValue ());
78
- }
79
-
80
89
final RubyRootNode rootNode = translator .parse (
81
90
new RubySource (source ),
82
- interactive ? ParserContext . EVAL : ParserContext .TOP_LEVEL ,
91
+ ParserContext .TOP_LEVEL ,
83
92
argumentNames ,
84
- declarationFrame ,
85
- ! interactive ,
93
+ null ,
94
+ true ,
86
95
null );
87
96
88
97
final RootCallTarget callTarget = Truffle .getRuntime ().createCallTarget (rootNode );
@@ -98,7 +107,7 @@ public Object execute(VirtualFrame frame) {
98
107
}
99
108
100
109
final Object value = callNode .call (RubyArguments .pack (
101
- declarationFrame ,
110
+ null ,
102
111
null ,
103
112
method ,
104
113
null ,
0 commit comments