Skip to content

Commit 610cea3

Browse files
committed
[GR-45043] ParserCache does not always have a RubyLanguage
PullRequest: truffleruby/4152
2 parents 61cf24b + 0a23e68 commit 610cea3

File tree

4 files changed

+33
-37
lines changed

4 files changed

+33
-37
lines changed

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

+11
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,17 @@ public String getSourcePath(Source source) {
913913
}
914914
}
915915

916+
@TruffleBoundary
917+
public static String getCorePath(Source source) {
918+
final String path = getPath(source);
919+
String coreLoadPath = OptionsCatalog.CORE_LOAD_PATH_KEY.getDefaultValue();
920+
if (path.startsWith(coreLoadPath)) {
921+
return "<internal:core> " + path.substring(coreLoadPath.length() + 1);
922+
} else {
923+
throw CompilerDirectives.shouldNotReachHere(path + " is not a core path starting with " + coreLoadPath);
924+
}
925+
}
926+
916927
/** Only use when no language/context is available (e.g. Node#toString). Prefer
917928
* {@link RubyContext#fileLine(SourceSection)} as it accounts for coreLoadPath and line offsets. */
918929
@TruffleBoundary

src/main/java/org/truffleruby/aot/ParserCache.java

+5-8
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import org.truffleruby.RubyLanguage;
2222
import org.truffleruby.core.CoreLibrary;
2323
import org.truffleruby.language.loader.ResourceLoader;
24-
import org.truffleruby.parser.ParseEnvironment;
25-
import org.truffleruby.parser.ParserContext;
2624
import org.truffleruby.parser.RubySource;
2725
import org.truffleruby.parser.YARPTranslatorDriver;
2826
import org.truffleruby.shared.options.OptionsCatalog;
@@ -39,7 +37,7 @@ public final class ParserCache {
3937
final Map<String, Pair<ParseResult, Source>> cache = new HashMap<>();
4038

4139
for (String coreFile : CoreLibrary.CORE_FILES) {
42-
//intern() to improve footprint
40+
// intern() to improve footprint
4341
final String path = (defaultCoreLibraryPath + coreFile).intern();
4442
final RubySource source = loadSource(path);
4543
cache.put(path, parse(source));
@@ -62,14 +60,13 @@ private static RubySource loadSource(String feature) {
6260
}
6361

6462
private static Pair<ParseResult, Source> parse(RubySource source) {
65-
var language = RubyLanguage.getCurrentLanguage();
6663
var yarpSource = YARPTranslatorDriver.createYARPSource(source.getBytes());
67-
var parseEnvironment = new ParseEnvironment(language, source, yarpSource, ParserContext.TOP_LEVEL, null);
64+
var sourcePath = RubyLanguage.getCorePath(source.getSource()).intern();
6865

69-
var parseResult = YARPTranslatorDriver.parseToYARPAST(language, source, Collections.emptyList(),
70-
parseEnvironment);
66+
var parseResult = YARPTranslatorDriver.parseToYARPAST(source, sourcePath, yarpSource, Collections.emptyList(),
67+
false);
7168

72-
YARPTranslatorDriver.handleWarningsErrorsNoContext(language, parseResult, source, yarpSource);
69+
YARPTranslatorDriver.handleWarningsErrorsNoContext(parseResult, sourcePath, yarpSource);
7370

7471
return Pair.create(parseResult, source.getSource());
7572
}

src/main/java/org/truffleruby/debug/TruffleDebugNodes.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@
106106
import com.oracle.truffle.api.nodes.NodeUtil;
107107
import com.oracle.truffle.api.object.Shape;
108108
import com.oracle.truffle.api.utilities.TriState;
109-
import org.truffleruby.parser.ParseEnvironment;
110109
import org.truffleruby.parser.ParserContext;
111110
import org.truffleruby.parser.RubySource;
112111
import org.truffleruby.parser.TranslatorEnvironment;
@@ -261,12 +260,12 @@ Object ast(Object code,
261260
var source = Source.newBuilder("ruby", new ByteBasedCharSequence(codeString), name).build();
262261
var rubySource = new RubySource(source, name);
263262

263+
var language = getLanguage();
264264
var yarpSource = YARPTranslatorDriver.createYARPSource(rubySource.getBytes());
265-
var parseEnvironment = new ParseEnvironment(getLanguage(), rubySource, yarpSource, ParserContext.TOP_LEVEL,
266-
this);
265+
String sourcePath = rubySource.getSourcePath(language).intern();
267266

268-
var parseResult = YARPTranslatorDriver.parseToYARPAST(getLanguage(), rubySource, Collections.emptyList(),
269-
parseEnvironment);
267+
var parseResult = YARPTranslatorDriver.parseToYARPAST(rubySource, sourcePath, yarpSource,
268+
Collections.emptyList(), language.options.FROZEN_STRING_LITERALS);
270269
var ast = parseResult.value;
271270

272271
return createString(fromJavaStringNode, ast.toString(), Encodings.UTF_8);

src/main/java/org/truffleruby/parser/YARPTranslatorDriver.java

+13-24
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ public RootCallTarget parse(RubySource rubySource, ParserContext parserContext,
156156
// Parse to the YARP AST
157157
final RubyDeferredWarnings rubyWarnings = new RubyDeferredWarnings();
158158

159+
final String sourcePath = rubySource.getSourcePath(language).intern();
160+
159161
// Only use the cache while loading top-level core library files, as eval() later could use
160162
// the same Source name but should not use the cache. For instance,
161163
// TOPLEVEL_BINDING.eval("self") would use the cache which is wrong.
@@ -168,12 +170,12 @@ public RootCallTarget parse(RubySource rubySource, ParserContext parserContext,
168170
parseResult = context.getMetricsProfiler().callWithMetrics(
169171
"parsing",
170172
source.getName(),
171-
() -> parseToYARPAST(language, rubySource, localsInScopes,
172-
parseEnvironment));
173+
() -> parseToYARPAST(rubySource, sourcePath, yarpSource, localsInScopes,
174+
language.options.FROZEN_STRING_LITERALS));
173175
printParseTranslateExecuteMetric("after-parsing", context, source);
174176
}
175177

176-
handleWarningsErrorsPrimitives(context, language, parseResult, rubySource, parseEnvironment, rubyWarnings);
178+
handleWarningsErrorsPrimitives(context, parseResult, rubySource, sourcePath, parseEnvironment, rubyWarnings);
177179

178180
var node = parseResult.value;
179181

@@ -355,18 +357,14 @@ private String getMethodName(ParserContext parserContext, MaterializedFrame pare
355357
}
356358
}
357359

358-
public static ParseResult parseToYARPAST(RubyLanguage language, RubySource rubySource,
359-
List<List<String>> localsInScopes, ParseEnvironment parseEnvironment) {
360+
public static ParseResult parseToYARPAST(RubySource rubySource, String sourcePath, Nodes.Source yarpSource,
361+
List<List<String>> localsInScopes, boolean frozenStringLiteral) {
360362
TruffleSafepoint.poll(DummyNode.INSTANCE);
361363

362-
// intern() to improve footprint
363-
String sourcePath = rubySource.getSourcePath(language).intern();
364-
365364
byte[] sourceBytes = rubySource.getBytes();
366365
final byte[] filepath = sourcePath.getBytes(Encodings.FILESYSTEM_CHARSET);
367366
int line = rubySource.getLineOffset() + 1;
368367
byte[] encoding = StringOperations.encodeAsciiBytes(rubySource.getEncoding().toString()); // encoding name is supposed to contain only ASCII characters
369-
boolean frozenStringLiteral = language.options.FROZEN_STRING_LITERALS;
370368
var version = ParsingOptions.SyntaxVersion.V3_3_0;
371369

372370
byte[][][] scopes;
@@ -400,17 +398,13 @@ public static ParseResult parseToYARPAST(RubyLanguage language, RubySource rubyS
400398
scopes);
401399
byte[] serializedBytes = Parser.parseAndSerialize(sourceBytes, parsingOptions);
402400

403-
Nodes.Source yarpSource = parseEnvironment.yarpSource;
404401
return YARPLoader.load(serializedBytes, yarpSource, rubySource);
405402
}
406403

407-
public static void handleWarningsErrorsPrimitives(RubyContext context, RubyLanguage language,
408-
ParseResult parseResult, RubySource rubySource, ParseEnvironment parseEnvironment,
404+
public static void handleWarningsErrorsPrimitives(RubyContext context, ParseResult parseResult,
405+
RubySource rubySource, String sourcePath, ParseEnvironment parseEnvironment,
409406
RubyDeferredWarnings rubyWarnings) {
410407

411-
// intern() to improve footprint
412-
String sourcePath = rubySource.getSourcePath(language).intern();
413-
414408
final ParseResult.Error[] errors = parseResult.errors;
415409

416410
// collect warnings generated by the parser
@@ -464,25 +458,20 @@ public static void handleWarningsErrorsPrimitives(RubyContext context, RubyLangu
464458
parseEnvironment.allowTruffleRubyPrimitives = allowTruffleRubyPrimitives;
465459
}
466460

467-
public static void handleWarningsErrorsNoContext(RubyLanguage language, ParseResult parseResult,
468-
RubySource rubySource, Nodes.Source yarpSource) {
461+
public static void handleWarningsErrorsNoContext(ParseResult parseResult, String sourcePath,
462+
Nodes.Source yarpSource) {
469463
if (parseResult.errors.length > 0) {
470464
var error = parseResult.errors[0];
471465
throw CompilerDirectives.shouldNotReachHere("Parse error in " +
472-
fileLineYARPSource(error.location, language, rubySource, yarpSource) + ": " + error.message);
466+
sourcePath + ":" + yarpSource.line(error.location.startOffset) + ": " + error.message);
473467
}
474468

475469
for (var warning : parseResult.warnings) {
476470
throw CompilerDirectives.shouldNotReachHere("Warning in " +
477-
fileLineYARPSource(warning.location, language, rubySource, yarpSource) + ": " + warning.message);
471+
sourcePath + ":" + yarpSource.line(warning.location.startOffset) + ": " + warning.message);
478472
}
479473
}
480474

481-
private static String fileLineYARPSource(Nodes.Location location, RubyLanguage language, RubySource rubySource,
482-
Nodes.Source yarpSource) {
483-
return rubySource.getSourcePath(language) + ":" + yarpSource.line(location.startOffset);
484-
}
485-
486475
public static Nodes.Source createYARPSource(byte[] sourceBytes) {
487476
return new Nodes.Source(sourceBytes);
488477
}

0 commit comments

Comments
 (0)