Skip to content

Commit 90afa7e

Browse files
committed
[GR-15990] Make core-load-path a language option
PullRequest: truffleruby/2500
2 parents e6b04d8 + f1defbf commit 90afa7e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+190
-184
lines changed

src/main/java/org/truffleruby/RubyContext.java

Lines changed: 2 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
import org.truffleruby.core.proc.RubyProc;
5757
import org.truffleruby.core.regexp.RegexpCacheKey;
5858
import org.truffleruby.core.rope.NativeRope;
59-
import org.truffleruby.core.rope.PathToRopeCache;
6059
import org.truffleruby.core.symbol.RubySymbol;
6160
import org.truffleruby.core.thread.ThreadManager;
6261
import org.truffleruby.core.time.GetTimeZoneNode;
@@ -94,7 +93,6 @@
9493
import com.oracle.truffle.api.instrumentation.Instrumenter;
9594
import com.oracle.truffle.api.nodes.IndirectCallNode;
9695
import com.oracle.truffle.api.source.Source;
97-
import com.oracle.truffle.api.source.SourceSection;
9896

9997
public class RubyContext {
10098

@@ -121,7 +119,7 @@ public class RubyContext {
121119
private final ObjectSpaceManager objectSpaceManager = new ObjectSpaceManager();
122120
private final SharedObjects sharedObjects = new SharedObjects(this);
123121
private final AtExitManager atExitManager = new AtExitManager(this);
124-
private final CallStackManager callStack = new CallStackManager(this);
122+
private final CallStackManager callStack;
125123
private final CoreExceptions coreExceptions;
126124
private final EncodingManager encodingManager;
127125
private final MetricsProfiler metricsProfiler = new MetricsProfiler(this);
@@ -138,7 +136,6 @@ public class RubyContext {
138136
private final Hashing hashing;
139137
@CompilationFinal private BacktraceFormatter defaultBacktraceFormatter;
140138
private final BacktraceFormatter userBacktraceFormatter;
141-
private final PathToRopeCache pathToRopeCache = new PathToRopeCache(this);
142139
@CompilationFinal private TruffleNFIPlatform truffleNFIPlatform;
143140
private final CoreLibrary coreLibrary;
144141
@CompilationFinal private CoreMethods coreMethods;
@@ -163,6 +160,7 @@ public RubyContext(RubyLanguage language, TruffleLanguage.Env env) {
163160

164161
this.logger = env.getLogger("");
165162
this.language = language;
163+
this.callStack = new CallStackManager(language, this);
166164
setEnv(env);
167165
this.preInitialized = preInitializing;
168166

@@ -351,11 +349,6 @@ private boolean compatibleOptions(Options oldOptions, Options newOptions, boolea
351349
return false;
352350
}
353351

354-
if (!newOptions.CORE_LOAD_PATH.equals(OptionsCatalog.CORE_LOAD_PATH_KEY.getDefaultValue())) {
355-
RubyLanguage.LOGGER.fine(notReusingContext + "--core-load-path is set: " + newOptions.CORE_LOAD_PATH);
356-
return false; // Should load the specified core files
357-
}
358-
359352
if (hadHome != hasHome) {
360353
RubyLanguage.LOGGER.fine(notReusingContext + "Ruby home is " + (hasHome ? "set" : "unset"));
361354
return false;
@@ -638,10 +631,6 @@ public CoverageManager getCoverageManager() {
638631
return coverageManager;
639632
}
640633

641-
public PathToRopeCache getPathToRopeCache() {
642-
return pathToRopeCache;
643-
}
644-
645634
public CodeLoader getCodeLoader() {
646635
return codeLoader;
647636
}
@@ -807,34 +796,6 @@ public WeakValueCache<RegexpCacheKey, Regex> getRegexpCache() {
807796
return regexpCache;
808797
}
809798

810-
/** {@link #getSourcePath(Source)} should be used instead whenever possible (i.e., when we can access the context).
811-
*
812-
* Returns the path of a Source. Returns the short, potentially relative, path for the main script. Note however
813-
* that the path of {@code eval(code, nil, filename)} is just {@code filename} and might not be absolute. */
814-
public static String getPath(Source source) {
815-
final String path = source.getPath();
816-
if (path != null) {
817-
return path;
818-
} else {
819-
// non-file sources: eval(), main_boot_source, etc
820-
final String name = source.getName();
821-
assert name != null;
822-
return name;
823-
}
824-
}
825-
826-
/** {@link RubyContext#getPath(Source)} but also handles core library sources. Ideally this method would be static
827-
* but for now the core load path is an option and it also depends on the current working directory. Once we have
828-
* Source metadata in Truffle we could use that to identify core library sources without needing the context. */
829-
public String getSourcePath(Source source) {
830-
final String path = RubyContext.getPath(source);
831-
if (path.startsWith(coreLibrary.coreLoadPath)) {
832-
return "<internal:core> " + path.substring(coreLibrary.coreLoadPath.length() + 1);
833-
} else {
834-
return RubyContext.getPath(source);
835-
}
836-
}
837-
838799
public String getPathRelativeToHome(String path) {
839800
if (path.startsWith(rubyHome) && path.length() > rubyHome.length()) {
840801
return path.substring(rubyHome.length() + 1);
@@ -863,35 +824,4 @@ public PrintStream getEnvErrStream() {
863824
return errStream;
864825
}
865826

866-
@TruffleBoundary
867-
public static String fileLine(SourceSection section) {
868-
if (section == null) {
869-
return "no source section";
870-
} else {
871-
final String path = getPath(section.getSource());
872-
873-
if (section.isAvailable()) {
874-
return path + ":" + section.getStartLine();
875-
} else {
876-
return path;
877-
}
878-
}
879-
}
880-
881-
@TruffleBoundary
882-
public static String filenameLine(SourceSection section) {
883-
if (section == null) {
884-
return "no source section";
885-
} else {
886-
final String path = getPath(section.getSource());
887-
final String filename = new File(path).getName();
888-
889-
if (section.isAvailable()) {
890-
return filename + ":" + section.getStartLine();
891-
} else {
892-
return filename;
893-
}
894-
}
895-
}
896-
897827
}

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010
package org.truffleruby;
1111

12+
import java.io.File;
13+
import java.io.IOException;
1214
import java.util.Arrays;
1315
import java.util.Objects;
1416
import java.util.concurrent.atomic.AtomicLong;
@@ -18,6 +20,8 @@
1820
import com.oracle.truffle.api.CompilerDirectives;
1921
import com.oracle.truffle.api.instrumentation.AllocationReporter;
2022
import com.oracle.truffle.api.object.Shape;
23+
import com.oracle.truffle.api.source.Source;
24+
import com.oracle.truffle.api.source.SourceSection;
2125
import org.graalvm.options.OptionDescriptors;
2226
import org.jcodings.Encoding;
2327
import org.truffleruby.builtins.PrimitiveManager;
@@ -55,6 +59,7 @@
5559
import org.truffleruby.core.range.RubyObjectRange;
5660
import org.truffleruby.core.regexp.RubyMatchData;
5761
import org.truffleruby.core.rope.CodeRange;
62+
import org.truffleruby.core.rope.PathToRopeCache;
5863
import org.truffleruby.core.rope.Rope;
5964
import org.truffleruby.core.rope.RopeCache;
6065
import org.truffleruby.core.string.CoreStrings;
@@ -153,6 +158,8 @@ public final class RubyLanguage extends TruffleLanguage<RubyContext> {
153158
.getRuntime()
154159
.createAssumption("SafepointManager");
155160

161+
@CompilationFinal public String coreLoadPath;
162+
@CompilationFinal public String corePath;
156163
public final CoreMethodAssumptions coreMethodAssumptions;
157164
public final CoreStrings coreStrings;
158165
public final CoreSymbols coreSymbols;
@@ -165,6 +172,7 @@ public final class RubyLanguage extends TruffleLanguage<RubyContext> {
165172
@CompilationFinal private AllocationReporter allocationReporter;
166173

167174
private final AtomicLong nextObjectID = new AtomicLong(ObjectSpaceManager.INITIAL_LANGUAGE_OBJECT_ID);
175+
private final PathToRopeCache pathToRopeCache = new PathToRopeCache(this);
168176

169177
private static final RubyObjectType objectType = new RubyObjectType();
170178

@@ -228,6 +236,37 @@ public RubyLanguage() {
228236
frozenStringLiterals = new FrozenStringLiterals(ropeCache);
229237
}
230238

239+
@TruffleBoundary
240+
public static String fileLine(SourceSection section) {
241+
if (section == null) {
242+
return "no source section";
243+
} else {
244+
final String path = getPath(section.getSource());
245+
246+
if (section.isAvailable()) {
247+
return path + ":" + section.getStartLine();
248+
} else {
249+
return path;
250+
}
251+
}
252+
}
253+
254+
@TruffleBoundary
255+
public static String filenameLine(SourceSection section) {
256+
if (section == null) {
257+
return "no source section";
258+
} else {
259+
final String path = getPath(section.getSource());
260+
final String filename = new File(path).getName();
261+
262+
if (section.isAvailable()) {
263+
return filename + ":" + section.getStartLine();
264+
} else {
265+
return filename;
266+
}
267+
}
268+
}
269+
231270
@TruffleBoundary
232271
public RubySymbol getSymbol(String string) {
233272
return symbolTable.getSymbol(string);
@@ -280,6 +319,8 @@ public RubyContext createContext(Env env) {
280319
}
281320
if (this.options == null) {
282321
this.options = new LanguageOptions(env, env.getOptions());
322+
this.coreLoadPath = buildCoreLoadPath(this.options.CORE_LOAD_PATH);
323+
this.corePath = coreLoadPath + File.separator + "core" + File.separator;
283324
primitiveManager.loadCoreMethodNodes(this.options);
284325
}
285326
}
@@ -467,6 +508,10 @@ public long getNextObjectID() {
467508
return id;
468509
}
469510

511+
public PathToRopeCache getPathToRopeCache() {
512+
return pathToRopeCache;
513+
}
514+
470515
private static Shape createShape(Class<? extends RubyDynamicObject> layoutClass) {
471516
return Shape
472517
.newBuilder()
@@ -481,4 +526,50 @@ protected boolean areOptionsCompatible(OptionValues firstOptions, OptionValues n
481526
return LanguageOptions.areOptionsCompatible(firstOptions, newOptions);
482527
}
483528

529+
/** {@link RubyLanguage#getSourcePath(Source)} should be used instead whenever possible (i.e., when we can access
530+
* the language).
531+
*
532+
* Returns the path of a Source. Returns the short, potentially relative, path for the main script. Note however
533+
* that the path of {@code eval(code, nil, filename)} is just {@code filename} and might not be absolute. */
534+
public static String getPath(Source source) {
535+
final String path = source.getPath();
536+
if (path != null) {
537+
return path;
538+
} else {
539+
// non-file sources: eval(), main_boot_source, etc
540+
final String name = source.getName();
541+
assert name != null;
542+
return name;
543+
}
544+
}
545+
546+
/** {@link RubyLanguage#getPath(Source)} but also handles core library sources. Ideally this method would be static
547+
* but for now the core load path is an option and it also depends on the current working directory. Once we have
548+
* Source metadata in Truffle we could use that to identify core library sources without needing the language. */
549+
public String getSourcePath(Source source) {
550+
final String path = getPath(source);
551+
if (path.startsWith(coreLoadPath)) {
552+
return "<internal:core> " + path.substring(coreLoadPath.length() + 1);
553+
} else {
554+
return getPath(source);
555+
}
556+
}
557+
558+
private static String buildCoreLoadPath(String coreLoadPath) {
559+
560+
while (coreLoadPath.endsWith("/")) {
561+
coreLoadPath = coreLoadPath.substring(0, coreLoadPath.length() - 1);
562+
}
563+
564+
if (coreLoadPath.startsWith(RubyLanguage.RESOURCE_SCHEME)) {
565+
return coreLoadPath;
566+
}
567+
568+
try {
569+
return new File(coreLoadPath).getCanonicalPath();
570+
} catch (IOException e) {
571+
throw CompilerDirectives.shouldNotReachHere(e);
572+
}
573+
}
574+
484575
}

src/main/java/org/truffleruby/builtins/PrimitiveNodeConstructor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
package org.truffleruby.builtins;
1111

12-
import org.truffleruby.RubyContext;
12+
import org.truffleruby.RubyLanguage;
1313
import org.truffleruby.core.array.ArrayUtils;
1414
import org.truffleruby.core.numeric.FixnumLowerNodeGen;
1515
import org.truffleruby.core.support.TypeNodes;
@@ -39,7 +39,7 @@ public RubyNode createInvokePrimitiveNode(Source source, SourceIndexLength sourc
3939
if (arguments.length != getPrimitiveArity()) {
4040
throw new Error(
4141
"Incorrect number of arguments (expected " + getPrimitiveArity() + ") at " +
42-
RubyContext.fileLine(sourceSection.toSourceSection(source)));
42+
RubyLanguage.fileLine(sourceSection.toSourceSection(source)));
4343
}
4444

4545
for (int n = 0; n < arguments.length; n++) {

src/main/java/org/truffleruby/cext/CExtNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ public abstract static class SourceFileNode extends CoreMethodArrayArgumentsNode
767767
@Specialization
768768
protected RubyString sourceFile() {
769769
final SourceSection sourceSection = getTopUserSourceSection("rb_sourcefile");
770-
final String file = getContext().getSourcePath(sourceSection.getSource());
770+
final String file = getLanguage().getSourcePath(sourceSection.getSource());
771771

772772
return makeStringNode.executeMake(file, UTF8Encoding.INSTANCE, CodeRange.CR_UNKNOWN);
773773
}

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010
package org.truffleruby.core;
1111

12-
import java.io.File;
1312
import java.io.IOException;
1413
import java.nio.file.FileVisitResult;
1514
import java.nio.file.Files;
@@ -253,9 +252,6 @@ public class CoreLibrary {
253252

254253
private final ConcurrentMap<String, Boolean> patchFiles;
255254

256-
public final String coreLoadPath;
257-
public final String corePath;
258-
259255
@TruffleBoundary
260256
private static SourceSection initCoreSourceSection() {
261257
final Source.SourceBuilder builder = Source.newBuilder(TruffleRuby.LANGUAGE_ID, "", "(core)");
@@ -271,24 +267,6 @@ private static SourceSection initCoreSourceSection() {
271267
return source.createUnavailableSection();
272268
}
273269

274-
private String buildCoreLoadPath() {
275-
String path = context.getOptions().CORE_LOAD_PATH;
276-
277-
while (path.endsWith("/")) {
278-
path = path.substring(0, path.length() - 1);
279-
}
280-
281-
if (path.startsWith(RubyLanguage.RESOURCE_SCHEME)) {
282-
return path;
283-
}
284-
285-
try {
286-
return new File(path).getCanonicalPath();
287-
} catch (IOException e) {
288-
throw CompilerDirectives.shouldNotReachHere(e);
289-
}
290-
}
291-
292270
private enum State {
293271
INITIALIZING,
294272
LOADING_RUBY_CORE,
@@ -302,8 +280,6 @@ private enum State {
302280
public CoreLibrary(RubyContext context, RubyLanguage language) {
303281
this.context = context;
304282
this.language = language;
305-
this.coreLoadPath = buildCoreLoadPath();
306-
this.corePath = coreLoadPath + File.separator + "core" + File.separator;
307283
this.node = SingletonClassNode.getUncached();
308284

309285
// Nothing in this constructor can use RubyContext.getCoreLibrary() as we are building it!
@@ -780,7 +756,7 @@ public void loadRubyCoreLibraryAndPostBoot() {
780756
state = State.LOADED;
781757
}
782758

783-
final RubySource source = loadCoreFile(coreLoadPath + file);
759+
final RubySource source = loadCoreFile(language.coreLoadPath + file);
784760
final RubyRootNode rootNode = context
785761
.getCodeLoader()
786762
.parse(source, ParserContext.TOP_LEVEL, null, null, true, node);

src/main/java/org/truffleruby/core/binding/BindingNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ protected Object sourceLocation(RubyBinding binding,
468468
return nil;
469469
} else {
470470
final RubyString file = makeStringNode.executeMake(
471-
getContext().getSourcePath(sourceSection.getSource()),
471+
getLanguage().getSourcePath(sourceSection.getSource()),
472472
UTF8Encoding.INSTANCE,
473473
CodeRange.CR_UNKNOWN);
474474
return createArray(new Object[]{ file, sourceSection.getStartLine() });

src/main/java/org/truffleruby/core/fiber/FiberManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ private void fiberMain(RubyContext context, RubyFiber fiber, RubyProc block, Nod
145145
final Thread thread = Thread.currentThread();
146146
final SourceSection sourceSection = block.sharedMethodInfo.getSourceSection();
147147
final String oldName = thread.getName();
148-
thread.setName(NAME_PREFIX + " id=" + thread.getId() + " from " + RubyContext.fileLine(sourceSection));
148+
thread.setName(NAME_PREFIX + " id=" + thread.getId() + " from " + RubyLanguage.fileLine(sourceSection));
149149

150150
start(fiber, thread, false);
151151

0 commit comments

Comments
 (0)