mirror of
https://github.com/enso-org/enso.git
synced 2024-11-13 02:09:56 +03:00
Eliminate compile time dependency on runtime-language-epb (#7611)
This commit is contained in:
parent
f3f2f06bd9
commit
e224eb350a
@ -1230,6 +1230,7 @@ lazy val `runtime-language-epb` =
|
||||
truffleDslSuppressWarnsSetting,
|
||||
instrumentationSettings
|
||||
)
|
||||
.dependsOn(`polyglot-api`)
|
||||
|
||||
/** Runs gu (GraalVM updater) command with given `args`.
|
||||
* For example `runGu(Seq("install", "js"))`.
|
||||
@ -1404,7 +1405,6 @@ lazy val runtime = (project in file("engine/runtime"))
|
||||
Benchmark / parallelExecution := false
|
||||
)
|
||||
.dependsOn(`common-polyglot-core-utils`)
|
||||
.dependsOn(`runtime-language-epb`)
|
||||
.dependsOn(`edition-updater`)
|
||||
.dependsOn(`interpreter-dsl`)
|
||||
.dependsOn(`library-manager`)
|
||||
@ -1532,6 +1532,7 @@ lazy val `runtime-with-instruments` =
|
||||
.dependsOn(`runtime-instrument-id-execution`)
|
||||
.dependsOn(`runtime-instrument-repl-debugger`)
|
||||
.dependsOn(`runtime-instrument-runtime-server`)
|
||||
.dependsOn(`runtime-language-epb`)
|
||||
|
||||
/* runtime-with-polyglot
|
||||
* ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -0,0 +1,47 @@
|
||||
package org.enso.polyglot;
|
||||
|
||||
import com.oracle.truffle.api.source.Source;
|
||||
import java.util.Arrays;
|
||||
|
||||
/** Lists all the languages supported in polyglot eval. */
|
||||
public enum ForeignLanguage {
|
||||
JS("js", "js"),
|
||||
PY("python", "python"),
|
||||
R("R", "r");
|
||||
|
||||
public static final String ID = "epb";
|
||||
|
||||
private final String truffleId;
|
||||
private final String syntacticTag;
|
||||
|
||||
ForeignLanguage(String truffleId, String syntacticTag) {
|
||||
this.truffleId = truffleId;
|
||||
this.syntacticTag = syntacticTag;
|
||||
}
|
||||
|
||||
/** @return a Truffle language ID associated with this language */
|
||||
public String getTruffleId() {
|
||||
return truffleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms an Enso-side syntactic language tag into a recognized language object.
|
||||
*
|
||||
* @param tag the tag to parse
|
||||
* @return a corresponding language value, or null if the language is not recognized
|
||||
*/
|
||||
public static ForeignLanguage getBySyntacticTag(String tag) {
|
||||
return Arrays.stream(values()).filter(l -> l.syntacticTag.equals(tag)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new source instance that can later be parsed by this class.
|
||||
*
|
||||
* @param foreignSource the foreign source to evaluate
|
||||
* @param name the name of the source
|
||||
* @return a source instance, parsable by the EPB language
|
||||
*/
|
||||
public Source buildSource(String foreignSource, String name) {
|
||||
return Source.newBuilder(ID, this + "#" + foreignSource, name).build();
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import com.oracle.truffle.api.TruffleLanguage;
|
||||
import java.util.function.Consumer;
|
||||
import org.enso.interpreter.epb.node.ContextRewrapNode;
|
||||
import org.enso.interpreter.epb.node.ForeignEvalNode;
|
||||
import org.enso.polyglot.ForeignLanguage;
|
||||
|
||||
/**
|
||||
* An internal language that serves as a bridge between Enso and other supported languages.
|
||||
@ -29,7 +30,7 @@ import org.enso.interpreter.epb.node.ForeignEvalNode;
|
||||
* provide context-switching facilities.
|
||||
*/
|
||||
@TruffleLanguage.Registration(
|
||||
id = EpbLanguage.ID,
|
||||
id = ForeignLanguage.ID,
|
||||
name = "Enso Polyglot Bridge",
|
||||
characterMimeTypes = {EpbLanguage.MIME},
|
||||
internal = true,
|
||||
@ -37,7 +38,6 @@ import org.enso.interpreter.epb.node.ForeignEvalNode;
|
||||
contextPolicy = TruffleLanguage.ContextPolicy.SHARED,
|
||||
services = Consumer.class)
|
||||
public class EpbLanguage extends TruffleLanguage<EpbContext> {
|
||||
public static final String ID = "epb";
|
||||
public static final String MIME = "application/epb";
|
||||
|
||||
@Override
|
||||
|
@ -1,45 +1,10 @@
|
||||
package org.enso.interpreter.epb;
|
||||
|
||||
import com.oracle.truffle.api.source.Source;
|
||||
import java.util.Arrays;
|
||||
import org.enso.polyglot.ForeignLanguage;
|
||||
|
||||
/** A class containing helpers for creating and parsing EPB code */
|
||||
public class EpbParser {
|
||||
private static final String separator = "#";
|
||||
|
||||
/** Lists all the languages supported in polyglot eval. */
|
||||
public enum ForeignLanguage {
|
||||
JS("js", "js"),
|
||||
PY("python", "python"),
|
||||
R("R", "r");
|
||||
|
||||
private final String truffleId;
|
||||
private final String syntacticTag;
|
||||
|
||||
ForeignLanguage(String truffleId, String syntacticTag) {
|
||||
this.truffleId = truffleId;
|
||||
this.syntacticTag = syntacticTag;
|
||||
}
|
||||
|
||||
/** @return a Truffle language ID associated with this language */
|
||||
public String getTruffleId() {
|
||||
return truffleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms an Enso-side syntactic language tag into a recognized language object.
|
||||
*
|
||||
* @param tag the tag to parse
|
||||
* @return a corresponding language value, or null if the language is not recognized
|
||||
*/
|
||||
public static ForeignLanguage getBySyntacticTag(String tag) {
|
||||
return Arrays.stream(values())
|
||||
.filter(l -> l.syntacticTag.equals(tag))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
/** A parsing result. */
|
||||
public static class Result {
|
||||
private final ForeignLanguage language;
|
||||
@ -69,19 +34,7 @@ public class EpbParser {
|
||||
*/
|
||||
public static Result parse(Source source) {
|
||||
String src = source.getCharacters().toString();
|
||||
String[] langAndCode = src.split(separator, 2);
|
||||
String[] langAndCode = src.split("#", 2);
|
||||
return new Result(ForeignLanguage.valueOf(langAndCode[0]), langAndCode[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new source instance that can later be parsed by this class.
|
||||
*
|
||||
* @param language the foreign language to use
|
||||
* @param foreignSource the foreign source to evaluate
|
||||
* @param name the name of the source
|
||||
* @return a source instance, parsable by the EPB language
|
||||
*/
|
||||
public static Source buildSource(ForeignLanguage language, String foreignSource, String name) {
|
||||
return Source.newBuilder(EpbLanguage.ID, language + separator + foreignSource, name).build();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import org.enso.interpreter.epb.EpbLanguage;
|
||||
import org.enso.interpreter.epb.EpbParser;
|
||||
import org.enso.interpreter.epb.runtime.ForeignParsingException;
|
||||
import org.enso.interpreter.epb.runtime.GuardedTruffleContext;
|
||||
import org.graalvm.polyglot.Context;
|
||||
|
||||
public class ForeignEvalNode extends RootNode {
|
||||
private final EpbParser.Result code;
|
||||
@ -72,7 +71,8 @@ public class ForeignEvalNode extends RootNode {
|
||||
CompilerDirectives.transferToInterpreterAndInvalidate();
|
||||
var foreignLang = code.getLanguage();
|
||||
String truffleLangId = foreignLang.getTruffleId();
|
||||
var installedLanguages = Context.getCurrent().getEngine().getLanguages();
|
||||
var context = EpbContext.get(this);
|
||||
var installedLanguages = context.getEnv().getInternalLanguages();
|
||||
if (!installedLanguages.containsKey(truffleLangId)) {
|
||||
this.parseException =
|
||||
new ForeignParsingException(truffleLangId, installedLanguages.keySet(), this);
|
||||
|
@ -13,7 +13,7 @@ public class ForeignMethodInvokeTest extends TestBase {
|
||||
|
||||
@BeforeClass
|
||||
public static void prepareCtx() {
|
||||
ctx = createDefaultContext();
|
||||
ctx = defaultContextBuilder("enso").build();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@ -27,10 +27,10 @@ public class ForeignMethodInvokeTest extends TestBase {
|
||||
// should fail with a Polyglot_Error, rather than crashing whole engine.
|
||||
String source = """
|
||||
from Standard.Base import all
|
||||
|
||||
|
||||
foreign python py_array = \"\"\"
|
||||
return [1,2,3]
|
||||
|
||||
|
||||
main =
|
||||
Panic.recover Any py_array
|
||||
""".trim();
|
@ -15,7 +15,6 @@ import org.enso.distribution.DistributionManager;
|
||||
import org.enso.distribution.Environment;
|
||||
import org.enso.distribution.locking.LockManager;
|
||||
import org.enso.distribution.locking.ThreadSafeFileLockManager;
|
||||
import org.enso.interpreter.epb.EpbLanguage;
|
||||
import org.enso.interpreter.instrument.NotificationHandler;
|
||||
import org.enso.interpreter.instrument.NotificationHandler.Forwarder;
|
||||
import org.enso.interpreter.instrument.NotificationHandler.TextMode$;
|
||||
@ -31,6 +30,7 @@ import org.enso.interpreter.runtime.tag.Patchable;
|
||||
import org.enso.interpreter.util.FileDetector;
|
||||
import org.enso.lockmanager.client.ConnectedLockManager;
|
||||
import org.enso.logger.masking.MaskingFactory;
|
||||
import org.enso.polyglot.ForeignLanguage;
|
||||
import org.enso.polyglot.LanguageInfo;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.enso.syntax2.Line;
|
||||
@ -69,7 +69,7 @@ import com.oracle.truffle.api.nodes.RootNode;
|
||||
defaultMimeType = LanguageInfo.MIME_TYPE,
|
||||
characterMimeTypes = {LanguageInfo.MIME_TYPE},
|
||||
contextPolicy = TruffleLanguage.ContextPolicy.EXCLUSIVE,
|
||||
dependentLanguages = {EpbLanguage.ID},
|
||||
dependentLanguages = {ForeignLanguage.ID},
|
||||
fileTypeDetectors = FileDetector.class,
|
||||
services= { Timer.class, NotificationHandler.Forwarder.class, LockManager.class }
|
||||
)
|
||||
@ -159,7 +159,7 @@ public final class EnsoLanguage extends TruffleLanguage<EnsoContext> {
|
||||
var env = context.getEnvironment();
|
||||
var preinit = env.getOptions().get(RuntimeOptions.PREINITIALIZE_KEY);
|
||||
if (preinit != null && preinit.length() > 0) {
|
||||
var epb = env.getInternalLanguages().get(EpbLanguage.ID);
|
||||
var epb = env.getInternalLanguages().get(ForeignLanguage.ID);
|
||||
var run = env.lookup(epb, Consumer.class);
|
||||
run.accept(preinit);
|
||||
}
|
||||
|
@ -7,8 +7,7 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.epb.node.CoercePrimitiveNode;
|
||||
import org.enso.interpreter.node.expression.foreign.CoerceNothing;
|
||||
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
@ -22,13 +21,12 @@ public class ReadArrayElementNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
||||
private @Child CoercePrimitiveNode coercion = CoercePrimitiveNode.build();
|
||||
private @Child CoerceNothing nothingCoercion = CoerceNothing.build();
|
||||
private @Child HostValueToEnsoNode toEnso = HostValueToEnsoNode.build();
|
||||
private final BranchProfile err = BranchProfile.create();
|
||||
|
||||
Object execute(Object array, long index) {
|
||||
try {
|
||||
return nothingCoercion.execute(coercion.execute(library.readArrayElement(array, index)));
|
||||
return toEnso.execute(library.readArrayElement(array, index));
|
||||
} catch (UnsupportedMessageException e) {
|
||||
err.enter();
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
|
@ -31,7 +31,7 @@ import org.enso.compiler.pass.resolve.{
|
||||
TypeNames,
|
||||
TypeSignatures
|
||||
}
|
||||
import org.enso.interpreter.epb.EpbParser
|
||||
import org.enso.polyglot.ForeignLanguage
|
||||
import org.enso.interpreter.node.callable.argument.ReadArgumentNode
|
||||
import org.enso.interpreter.node.callable.function.{
|
||||
BlockNode,
|
||||
@ -1684,7 +1684,7 @@ class IrToTruffle(
|
||||
val bodyExpr = body match {
|
||||
case IR.Foreign.Definition(lang, code, _, _, _) =>
|
||||
buildForeignBody(
|
||||
EpbParser.ForeignLanguage.getBySyntacticTag(lang),
|
||||
ForeignLanguage.getBySyntacticTag(lang),
|
||||
code,
|
||||
arguments.map(_.name.name),
|
||||
argSlotIdxs
|
||||
@ -1746,12 +1746,12 @@ class IrToTruffle(
|
||||
}
|
||||
|
||||
private def buildForeignBody(
|
||||
language: EpbParser.ForeignLanguage,
|
||||
language: ForeignLanguage,
|
||||
code: String,
|
||||
argumentNames: List[String],
|
||||
argumentSlotIdxs: List[Int]
|
||||
): RuntimeExpression = {
|
||||
val src = EpbParser.buildSource(language, code, scopeName)
|
||||
val src = language.buildSource(code, scopeName)
|
||||
val foreignCt = context.getEnvironment
|
||||
.parseInternal(src, argumentNames: _*)
|
||||
val argumentReaders = argumentSlotIdxs
|
||||
|
@ -12,8 +12,7 @@ import org.enso.compiler.pass.analyse.{
|
||||
}
|
||||
import org.enso.compiler.pass.lint.UnusedBindings
|
||||
import org.enso.compiler.pass.optimise.LambdaConsolidate
|
||||
import org.enso.interpreter.epb.EpbParser
|
||||
import org.enso.interpreter.epb.EpbParser.ForeignLanguage
|
||||
import org.enso.polyglot.ForeignLanguage
|
||||
|
||||
import scala.annotation.{tailrec}
|
||||
|
||||
@ -299,7 +298,7 @@ case object GenerateMethodBodies extends IRPass {
|
||||
@tailrec
|
||||
private def findForeignDefinition(
|
||||
body: IR.Expression,
|
||||
lang: Option[EpbParser.ForeignLanguage]
|
||||
lang: Option[ForeignLanguage]
|
||||
): Option[IR.Foreign.Definition] = {
|
||||
body match {
|
||||
case foreignDef: IR.Foreign.Definition =>
|
||||
|
@ -39,8 +39,8 @@ public abstract class TestBase {
|
||||
return context;
|
||||
}
|
||||
|
||||
protected static Context.Builder defaultContextBuilder() {
|
||||
return Context.newBuilder()
|
||||
protected static Context.Builder defaultContextBuilder(String... languages) {
|
||||
return Context.newBuilder(languages)
|
||||
.allowExperimentalOptions(true)
|
||||
.allowIO(IOAccess.ALL)
|
||||
.allowAllAccess(true)
|
||||
|
Loading…
Reference in New Issue
Block a user