Skip to content

Commit 873c418

Browse files
Towards a ClassPath per Package
1 parent 76070ba commit 873c418

File tree

6 files changed

+50
-27
lines changed

6 files changed

+50
-27
lines changed

engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/interop/java/AddToClassPathNode.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.oracle.truffle.api.dsl.Specialization;
66
import com.oracle.truffle.api.nodes.Node;
77
import java.io.File;
8+
import java.util.Collections;
89
import org.enso.interpreter.dsl.BuiltinMethod;
910
import org.enso.interpreter.node.expression.builtin.text.util.ExpectStringNode;
1011
import org.enso.interpreter.runtime.EnsoContext;
@@ -27,7 +28,7 @@ static AddToClassPathNode build() {
2728
Object doExecute(Object path, @Cached ExpectStringNode expectStringNode) {
2829
var ctx = EnsoContext.get(this);
2930
var file = ctx.getTruffleFile(new File(expectStringNode.execute(path)));
30-
ctx.addToClassPath(file);
31+
ctx.createClassPath(Collections.singletonList(file));
3132
return ctx.getBuiltins().nothing();
3233
}
3334
}

engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/interop/java/LookupClassNode.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static LookupClassNode build() {
2121
@Specialization
2222
@CompilerDirectives.TruffleBoundary
2323
Object doExecute(Object name, @Cached("build()") ExpectStringNode expectStringNode) {
24-
return EnsoContext.get(this).lookupJavaClass(expectStringNode.execute(name));
24+
return EnsoContext.get(this).lookupJavaClass(null, expectStringNode.execute(name));
2525
}
2626

2727
abstract Object execute(Object name);

engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java

+34-18
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.ArrayList;
2929
import java.util.Arrays;
3030
import java.util.HashSet;
31+
import java.util.List;
3132
import java.util.Optional;
3233
import java.util.Set;
3334
import java.util.UUID;
@@ -424,28 +425,42 @@ public Optional<Module> findModuleByExpressionId(UUID expressionId) {
424425
}
425426

426427
/**
427-
* Modifies the classpath to use to lookup {@code polyglot java} imports.
428+
* Creates a class path. A class path is capable to load Java classes in an isolated manner.
428429
*
429-
* @param file the file to register
430+
* @param files files to register
430431
*/
431432
@TruffleBoundary
432-
public void addToClassPath(TruffleFile file) {
433-
if (findGuestJava() == null) {
434-
try {
435-
var url = file.toUri().toURL();
436-
hostClassLoader.add(url);
437-
} catch (MalformedURLException ex) {
438-
throw new IllegalStateException(ex);
433+
public EnsoClassPath createClassPath(List<TruffleFile> files) {
434+
return new EnsoClassPath(files);
435+
}
436+
437+
public final class EnsoClassPath {
438+
// private final TruffleFile[] files;
439+
440+
private EnsoClassPath(List<TruffleFile> files) {
441+
for (var f : files) {
442+
add(f);
439443
}
440-
} else {
441-
try {
442-
var path = new File(file.toUri()).getAbsoluteFile();
443-
if (!path.exists()) {
444-
throw new IllegalStateException("File not found " + path);
444+
}
445+
446+
private void add(TruffleFile file) {
447+
if (findGuestJava() == null) {
448+
try {
449+
var url = file.toUri().toURL();
450+
hostClassLoader.add(url);
451+
} catch (MalformedURLException ex) {
452+
throw new IllegalStateException(ex);
453+
}
454+
} else {
455+
try {
456+
var path = new File(file.toUri()).getAbsoluteFile();
457+
if (!path.exists()) {
458+
throw new IllegalStateException("File not found " + path);
459+
}
460+
InteropLibrary.getUncached().invokeMember(findGuestJava(), "addPath", path.getPath());
461+
} catch (InteropException ex) {
462+
throw new IllegalStateException(ex);
445463
}
446-
InteropLibrary.getUncached().invokeMember(findGuestJava(), "addPath", path.getPath());
447-
} catch (InteropException ex) {
448-
throw new IllegalStateException(ex);
449464
}
450465
}
451466
}
@@ -518,11 +533,12 @@ public boolean isColorTerminalOutput() {
518533
* resolves to an inner class, then the import of the outer class is resolved, and the inner class
519534
* is looked up by iterating the members of the outer class via Truffle's interop protocol.
520535
*
536+
* @param pkg Enso package to load the class for
521537
* @param className Fully qualified class name, can also be nested static inner class.
522538
* @return If the java class is found, return it, otherwise return null.
523539
*/
524540
@TruffleBoundary
525-
public Object lookupJavaClass(String className) {
541+
public Object lookupJavaClass(Package<?> pkg, String className) {
526542
var binaryName = new StringBuilder(className);
527543
var collectedExceptions = new ArrayList<Exception>();
528544
for (; ; ) {

engine/runtime/src/main/java/org/enso/interpreter/runtime/TruffleCompilerContext.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public void truffleRunCodegen(
147147
var s =
148148
org.enso.interpreter.runtime.scope.ModuleScope.Builder.fromCompilerModuleScopeBuilder(
149149
scopeBuilder);
150-
new IrToTruffle(context, m.getSource(), s, config).run(module.getIr());
150+
new IrToTruffle(context, m.getSource(), s, config).run(module.getPackage(), module.getIr());
151151
}
152152

153153
// module related

engine/runtime/src/main/scala/org/enso/interpreter/runtime/DefaultPackageRepository.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ private class DefaultPackageRepository(
197197
isLibrary: Boolean
198198
): Unit = {
199199
val extensions = pkg.listPolyglotExtensions("java")
200-
extensions.foreach(context.addToClassPath)
200+
context.createClassPath(extensions.asJava)
201201

202202
val (regularModules, syntheticModulesMetadata) = pkg
203203
.listSources()

engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala

+11-5
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class IrToTruffle(
153153
*
154154
* @param ir the IR to generate code for
155155
*/
156-
def run(ir: Module): Unit = processModule(ir)
156+
def run(p: org.enso.pkg.Package[_], ir: Module): Unit = processModule(p, ir)
157157

158158
/** Executes the codegen pass on an inline input.
159159
*
@@ -186,7 +186,10 @@ class IrToTruffle(
186186
*
187187
* @param module the module for which code should be generated
188188
*/
189-
private def processModule(module: Module): Unit = {
189+
private def processModule(
190+
p: org.enso.pkg.Package[_],
191+
module: Module
192+
): Unit = {
190193
generateReExportBindings(module)
191194
val bindingsMap =
192195
module
@@ -197,7 +200,7 @@ class IrToTruffle(
197200

198201
registerModuleExports(bindingsMap)
199202
registerModuleImports(bindingsMap)
200-
registerPolyglotImports(module)
203+
registerPolyglotImports(p, module)
201204

202205
registerTypeDefinitions(module)
203206
registerMethodDefinitions(module)
@@ -232,10 +235,13 @@ class IrToTruffle(
232235
}
233236
}
234237

235-
private def registerPolyglotImports(module: Module): Unit =
238+
private def registerPolyglotImports(
239+
p: org.enso.pkg.Package[_],
240+
module: Module
241+
): Unit =
236242
module.imports.foreach {
237243
case poly @ imports.Polyglot(i: imports.Polyglot.Java, _, _, _, _) =>
238-
var hostSymbol = context.lookupJavaClass(i.getJavaName)
244+
var hostSymbol = context.lookupJavaClass(p, i.getJavaName)
239245
if (hostSymbol == null) {
240246
val err = Text.create(
241247
s"Incorrect polyglot java import: ${i.getJavaName}"

0 commit comments

Comments
 (0)