Skip to content

Commit bc54e9b

Browse files
committed
Use the parser cache for the main script as well
1 parent 6e7eb99 commit bc54e9b

File tree

4 files changed

+50
-37
lines changed

4 files changed

+50
-37
lines changed

src/main/java/org/truffleruby/RubyLanguage.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@
123123
id = TruffleRuby.LANGUAGE_ID,
124124
implementationName = TruffleRuby.FORMAL_NAME,
125125
version = TruffleRuby.LANGUAGE_VERSION,
126-
characterMimeTypes = { RubyLanguage.MIME_TYPE, RubyLanguage.MIME_TYPE_COVERAGE },
126+
characterMimeTypes = {
127+
RubyLanguage.MIME_TYPE,
128+
RubyLanguage.MIME_TYPE_COVERAGE,
129+
RubyLanguage.MIME_TYPE_MAIN_SCRIPT },
127130
defaultMimeType = RubyLanguage.MIME_TYPE,
128131
dependentLanguages = { "nfi", "llvm", "regex" },
129132
fileTypeDetectors = RubyFileTypeDetector.class)
@@ -143,7 +146,8 @@ public final class RubyLanguage extends TruffleLanguage<RubyContext> {
143146
/** Do not access directly, instead use {@link #getMimeType(boolean)} */
144147
static final String MIME_TYPE = "application/x-ruby";
145148
public static final String MIME_TYPE_COVERAGE = "application/x-ruby;coverage=true";
146-
public static final String[] MIME_TYPES = { MIME_TYPE, MIME_TYPE_COVERAGE };
149+
public static final String MIME_TYPE_MAIN_SCRIPT = "application/x-ruby;main-script=true";
150+
public static final String[] MIME_TYPES = { MIME_TYPE, MIME_TYPE_COVERAGE, MIME_TYPE_MAIN_SCRIPT };
147151

148152
public static final String PLATFORM = String.format(
149153
"%s-%s%s",
@@ -248,7 +252,7 @@ public final class RubyLanguage extends TruffleLanguage<RubyContext> {
248252
.layout(ClassVariableStorage.class)
249253
.build();
250254

251-
public final ThreadLocal<ParsingParameters> parsingRequestParams = new ThreadLocal<ParsingParameters>();
255+
public final ThreadLocal<ParsingParameters> parsingRequestParams = new ThreadLocal<>();
252256

253257
public RubyLanguage() {
254258
coreMethodAssumptions = new CoreMethodAssumptions(this);
@@ -441,31 +445,36 @@ public static RubyLanguage getCurrentLanguage() {
441445

442446
@Override
443447
protected RootCallTarget parse(ParsingRequest request) {
448+
final Source source = request.getSource();
449+
444450
final ParsingParameters parsingParameters = parsingRequestParams.get();
445451
if (parsingParameters != null) { // from #require or core library
446-
assert parsingParameters.getSource().equals(request.getSource());
452+
assert parsingParameters.getSource().equals(source);
447453
final RubySource rubySource = new RubySource(
448-
request.getSource(),
454+
source,
449455
parsingParameters.getPath(),
450456
parsingParameters.getRope());
457+
final ParserContext parserContext = MIME_TYPE_MAIN_SCRIPT.equals(source.getMimeType())
458+
? ParserContext.TOP_LEVEL_FIRST
459+
: ParserContext.TOP_LEVEL;
451460
return RubyLanguage.getCurrentContext().getCodeLoader().parse(
452461
rubySource,
453-
ParserContext.TOP_LEVEL,
462+
parserContext,
454463
null,
455464
null,
456465
true,
457466
parsingParameters.getCurrentNode());
458467
}
459468

460-
if (request.getSource().isInteractive()) {
461-
return Truffle.getRuntime().createCallTarget(new RubyEvalInteractiveRootNode(this, request.getSource()));
469+
if (source.isInteractive()) {
470+
return Truffle.getRuntime().createCallTarget(new RubyEvalInteractiveRootNode(this, source));
462471
} else {
463472
final RubyContext context = Objects.requireNonNull(getCurrentContext());
464473
return Truffle.getRuntime().createCallTarget(
465474
new RubyParsingRequestNode(
466475
this,
467476
context,
468-
request.getSource(),
477+
source,
469478
request.getArgumentNames().toArray(StringUtils.EMPTY_STRING_ARRAY)));
470479
}
471480
}

src/main/java/org/truffleruby/language/TruffleBootNodes.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
import com.oracle.truffle.api.RootCallTarget;
1818
import com.oracle.truffle.api.library.CachedLibrary;
1919
import com.oracle.truffle.api.nodes.NodeUtil;
20+
import org.graalvm.collections.Pair;
2021
import org.graalvm.options.OptionDescriptor;
2122
import org.jcodings.specific.UTF8Encoding;
2223
import org.truffleruby.RubyContext;
24+
import org.truffleruby.RubyLanguage;
2325
import org.truffleruby.builtins.CoreMethod;
2426
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
2527
import org.truffleruby.builtins.CoreMethodNode;
@@ -28,6 +30,7 @@
2830
import org.truffleruby.core.array.RubyArray;
2931
import org.truffleruby.core.rope.CodeRange;
3032
import org.truffleruby.core.rope.RopeOperations;
33+
import org.truffleruby.core.rope.Rope;
3134
import org.truffleruby.core.string.RubyString;
3235
import org.truffleruby.core.string.StringNodes.MakeStringNode;
3336
import org.truffleruby.core.symbol.RubySymbol;
@@ -134,13 +137,10 @@ protected int main(Object kind, Object toExecute,
134137
if (getContext().getOptions().SYNTAX_CHECK) {
135138
checkSyntax.call(coreLibrary().truffleBootModule, "check_syntax", source);
136139
} else {
137-
final RootCallTarget callTarget = getContext().getCodeLoader().parse(
138-
source,
139-
ParserContext.TOP_LEVEL_FIRST,
140-
null,
141-
null,
142-
true,
143-
null);
140+
final Pair<Source, Rope> sourceRopePair = Pair.create(source.getSource(), source.getRope());
141+
final RootCallTarget callTarget = getContext()
142+
.getCodeLoader()
143+
.parseTopLevelWithCache(sourceRopePair, null);
144144

145145
final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(
146146
callTarget,
@@ -173,39 +173,38 @@ private void setArgvGlobals() {
173173
}
174174

175175
private RubySource loadMainSourceSettingDollarZero(String kind, String toExecute) {
176-
final RubySource source;
176+
final RubySource rubySource;
177177
final Object dollarZeroValue;
178178
final MainLoader mainLoader = new MainLoader(getContext(), getLanguage());
179179
try {
180180
switch (kind) {
181-
case "FILE": {
182-
source = mainLoader.loadFromFile(getContext().getEnv(), this, toExecute);
181+
case "FILE":
182+
rubySource = mainLoader.loadFromFile(getContext().getEnv(), this, toExecute);
183183
dollarZeroValue = utf8(toExecute);
184-
}
185184
break;
186185

187-
case "STDIN": {
188-
source = mainLoader.loadFromStandardIn(this, "-");
186+
case "STDIN":
187+
rubySource = mainLoader.loadFromStandardIn(this, "-");
189188
dollarZeroValue = utf8("-");
190-
}
191189
break;
192190

193-
case "INLINE": {
194-
source = mainLoader.loadFromCommandLineArgument(toExecute);
191+
case "INLINE":
192+
rubySource = mainLoader.loadFromCommandLineArgument(toExecute);
195193
dollarZeroValue = utf8("-e");
196-
}
197194
break;
198195

199196
default:
200-
throw new IllegalStateException();
197+
throw CompilerDirectives.shouldNotReachHere(kind);
201198
}
202199
} catch (IOException e) {
203200
throw new RaiseException(getContext(), coreExceptions().ioError(e, this));
204201
}
202+
assert RubyLanguage.MIME_TYPE_MAIN_SCRIPT.equals(rubySource.getSource().getMimeType());
205203

206204
int index = getLanguage().getGlobalVariableIndex("$0");
207205
getContext().getGlobalVariableStorage(index).setValueInternal(dollarZeroValue);
208-
return source;
206+
207+
return rubySource;
209208
}
210209

211210
private RubyString utf8(String string) {

src/main/java/org/truffleruby/language/loader/FileLoader.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public Pair<Source, Rope> loadFile(String path) throws IOException {
7373

7474
final byte[] sourceBytes = file.readAllBytes();
7575
final Rope sourceRope = RopeOperations.create(sourceBytes, UTF8Encoding.INSTANCE, CodeRange.CR_UNKNOWN);
76-
final Source source = buildSource(file, path, sourceRope, isInternal(path));
76+
final Source source = buildSource(file, path, sourceRope, isInternal(path), false);
7777
return Pair.create(source, sourceRope);
7878
}
7979

@@ -120,7 +120,7 @@ private static boolean isStdLibRubyOrCExtFile(TruffleFile relativePathFromHome)
120120
return relativePathFromHome.startsWith("lib");
121121
}
122122

123-
Source buildSource(TruffleFile file, String path, Rope sourceRope, boolean internal) {
123+
Source buildSource(TruffleFile file, String path, Rope sourceRope, boolean internal, boolean mainSource) {
124124
/* I'm not sure why we need to explicitly set a MIME type here - we say it's Ruby and this is the only and
125125
* default MIME type that Ruby supports.
126126
*
@@ -138,7 +138,9 @@ Source buildSource(TruffleFile file, String path, Rope sourceRope, boolean inter
138138
* which are not reloaded since Coverage.result should not report coverage, so it seems really difficult to do
139139
* any caching when coverage is enabled. */
140140
final boolean coverageEnabled = language.coverageManager.isEnabled();
141-
final String mimeType = RubyLanguage.getMimeType(coverageEnabled);
141+
final String mimeType = mainSource
142+
? RubyLanguage.MIME_TYPE_MAIN_SCRIPT
143+
: RubyLanguage.getMimeType(coverageEnabled);
142144

143145
final Source source = Source
144146
.newBuilder(TruffleRuby.LANGUAGE_ID, file)

src/main/java/org/truffleruby/language/loader/MainLoader.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,21 @@ public MainLoader(RubyContext context, RubyLanguage language) {
4040
}
4141

4242
public RubySource loadFromCommandLineArgument(String code) {
43-
final Source source = Source.newBuilder(TruffleRuby.LANGUAGE_ID, code, "-e").build();
43+
final Source source = Source
44+
.newBuilder(TruffleRuby.LANGUAGE_ID, code, "-e")
45+
.mimeType(RubyLanguage.MIME_TYPE_MAIN_SCRIPT)
46+
.build();
4447
return new RubySource(source, "-e");
4548
}
4649

4750
public RubySource loadFromStandardIn(Node currentNode, String path) throws IOException {
4851
byte[] sourceBytes = readAllOfStandardIn();
4952
final Rope sourceRope = transformScript(currentNode, path, sourceBytes);
5053

51-
final Source source = Source.newBuilder(
52-
TruffleRuby.LANGUAGE_ID,
53-
RopeOperations.decodeOrEscapeBinaryRope(sourceRope),
54-
path).build();
54+
final Source source = Source
55+
.newBuilder(TruffleRuby.LANGUAGE_ID, RopeOperations.decodeOrEscapeBinaryRope(sourceRope), path)
56+
.mimeType(RubyLanguage.MIME_TYPE_MAIN_SCRIPT)
57+
.build();
5558
return new RubySource(source, path, sourceRope);
5659
}
5760

@@ -96,7 +99,7 @@ public RubySource loadFromFile(Env env, Node currentNode, String mainPath) throw
9699
byte[] sourceBytes = file.readAllBytes();
97100
final Rope sourceRope = transformScript(currentNode, mainPath, sourceBytes);
98101

99-
final Source mainSource = fileLoader.buildSource(file, mainPath, sourceRope, false);
102+
final Source mainSource = fileLoader.buildSource(file, mainPath, sourceRope, false, true);
100103

101104
return new RubySource(mainSource, mainPath, sourceRope);
102105
}

0 commit comments

Comments
 (0)