Skip to content

Commit

Permalink
Replace IOContexts with execution env and contexts (#6171)
Browse files Browse the repository at this point in the history
As per design, IOContexts controlled via type signatures are going away. They are replaced by explicit `Context.if_enabled` runtime checks that will be added to particular method implementations.

`production`/`development` `IOPermissions` are replaced with `live` and `design` execution enviornment. Currently, the `live` env has a hardcoded list of allowed contexts i.e. `Input` and `Output`.

# Important Notes
As per design PR-55. Closes #6129. Closes #6131.
  • Loading branch information
hubertp authored Apr 6, 2023
1 parent e7668eb commit 3cce3b3
Show file tree
Hide file tree
Showing 32 changed files with 700 additions and 271 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@
- [Detect potential name conflicts between exported types and FQNs][5966]
- [Ensure calls involving warnings remain instrumented][6067]
- [One can define lazy atom fields][6151]
- [Replace IOContexts with Execution Environment and generic Context][6171]

[3227]: https://github.com/enso-org/enso/pull/3227
[3248]: https://github.com/enso-org/enso/pull/3248
Expand Down Expand Up @@ -780,6 +781,7 @@
[5966]: https://github.com/enso-org/enso/pull/5966
[6067]: https://github.com/enso-org/enso/pull/6067
[6151]: https://github.com/enso-org/enso/pull/6151
[6171]: https://github.com/enso-org/enso/pull/6171

# Enso 2.0.0-alpha.18 (2021-10-12)

Expand Down
19 changes: 14 additions & 5 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ type Arithmetic_Error

@Builtin_Type
type Incomparable_Values
## An error that indicates that the two values are not comparable
## An error that indicates that the two values are not comparable.

Arguments:
- left: The left value (first operand)
- right: The right value (second operand)
- left: The left value (first operand).
- right: The right value (second operand).
Error left right

## PRIVATE
Expand Down Expand Up @@ -214,7 +214,7 @@ type Module_Does_Not_Exist
@Builtin_Type
type Invalid_Conversion_Target
## PRIVATE
An error that occurs when the specified value cannot be converted to a given type
An error that occurs when the specified value cannot be converted to a given type.

Arguments:
- target: the type trying to be converted to.
Expand All @@ -223,10 +223,19 @@ type Invalid_Conversion_Target
@Builtin_Type
type No_Such_Conversion
## PRIVATE
An error that occurs when the conversion from one type to another does not exist
An error that occurs when the conversion from one type to another does not exist.

Arguments:
- target: the type trying to be converted to.
- that: the value to be converted.
- conversion: the conversion that was attempted.
Error target that conversion

@Builtin_Type
type Forbidden_Operation
## PRIVATE
An error that occurs when the action is not allowed to perform the operation in the given context.

Arguments:
- operation: attempted context that is not allowed.
Error operation
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import project.Data.Text.Text
import project.Nothing.Nothing
import project.Panic.Panic

@Builtin_Type
type Unimplemented
## UNSTABLE

Expand Down
109 changes: 95 additions & 14 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import project.Any.Any
import project.Data.Array.Array
import project.Data.Boolean.Boolean
import project.Data.Text.Text
import project.Data.Vector.Vector
import project.Errors.Common.Forbidden_Operation
import project.Function.Function
import project.Nothing.Nothing
import project.Panic.Panic
import project.Polyglot.Polyglot
import project.Runtime.Source_Location.Source_Location

from project.Data.Index_Sub_Range.Index_Sub_Range import First, Last
from project.Runtime.Context import Input,Output

## Utilities for interacting with the runtime.

Expand Down Expand Up @@ -109,33 +114,109 @@ type Stack_Trace_Element
## PRIVATE
ADVANCED

Types indicating allowed IO operations
type IO_Permissions
Type indicating allowed execution context.

@Builtin_Type
type Context
## PRIVATE
ADVANCED
Input
## PRIVATE
ADVANCED
Output

## PRIVATE
ADVANCED

Returns the name of the context.

name : Text
name self =
case self of
Input -> "Input"
Output -> "Output"

## PRIVATE
ADVANCED

Checks whether the context is enabled. If it is, evaluates the provided
function and returns the result. If not, panics.

Arguments:
- environment: Name of the execution environment.
- context: The context to enable.
- action: Action to be performed with the context enabled.
if_enabled : Function -> Text -> Any
if_enabled self ~action environment=Runtime.current_execution_environment =
if self.is_enabled environment then action else Panic.throw (Forbidden_Operation.Error self.name)

## PRIVATE
ADVANCED

Checks whether the permission is enabled in the given environment.

Arguments:
- environment: Name of the execution environment.
- context: The context to enable.
is_enabled : Text -> Boolean
is_enabled self environment=Runtime.current_execution_environment = @Builtin_Method "Context.is_enabled"


## PRIVATE
ADVANCED

Allows an action in the `Input` context to be performed in the given `env`,
regardless of the Env configuration.
Returns the name of the current execution environment.
current_execution_environment : Text
current_execution_environment = @Builtin_Method "Runtime.current_execution_environment"

This can be used to enable certain nodes to run their actions in the
interactive mode, even if the configuration forbids it.
allow_input_in : Text -> Any -> Any
allow_input_in env ~action = @Builtin_Method "Runtime.allow_input_in"
## PRIVATE
ADVANCED

Enables a specific context in the provided runtime environment for the duration of the execution of the action.

Arguments:
- environment: Name of the execution environment.
- context: The context to enable.
- action: Action to be performed with the context enabled.
with_enabled_context : Context -> Function -> Text -> Any
with_enabled_context context ~action environment=Runtime.current_execution_environment = with_enabled_context_builtin context action environment

## PRIVATE
ADVANCED

Enables a specific context in the provided runtime environment for the duration of the execution of the action.

This method is internal, using `with_enabled_context` is preferred as it provides correct defaults.

Arguments:
- environment: Name of the execution environment.
- context: The context to enable.
- action: Action to be performed with the context enabled.
with_enabled_context_builtin : Context -> Function -> Text -> Any
with_enabled_context_builtin context ~action environment = @Builtin_Method "Runtime.with_enabled_context_builtin"

## PRIVATE
ADVANCED

Allows an action in the `Output` context to be performed in the given `env`,
regardless of the Env configuration.
Disables a specific context in the provided runtime environment for the duration of the execution of the action.

Arguments:
- environment: Name of the execution environment.
- context: The context to disable.
- action: Action to be performed with the context disabled.
with_disabled_context : Context -> Function -> Text -> Any
with_disabled_context context ~action environment=Runtime.current_execution_environment = with_disabled_context_builtin context action environment

This can be used to enable certain nodes to run their actions in the
interactive mode, even if the configuration forbids it.
allow_output_in : Text -> Any -> Any
allow_output_in env ~action = @Builtin_Method "Runtime.allow_output_in"
## PRIVATE
ADVANCED

Disables a specific context in the provided runtime environment for the duration of the execution of the action.

This method is internal, using `with_disabled_context` is preferred as it provides correct defaults.

Arguments:
- environment: Name of the execution environment.
- context: The context to disable.
- action: Action to be performed with the context disabled.
with_disabled_context_builtin : Context -> Function -> Text -> Any
with_disabled_context_builtin context ~action environment = @Builtin_Method "Runtime.with_disabled_context_builtin"
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class ContextFactory {
* @param useGlobalIrCacheLocation whether or not to use the global IR cache
* location
* @param options additional options for the Context
* @param executionEnvironment optional name of the execution environment to use during execution
* @return configured Context instance
*/
def create(
Expand All @@ -40,8 +41,12 @@ class ContextFactory {
strictErrors: Boolean = false,
useGlobalIrCacheLocation: Boolean = true,
enableAutoParallelism: Boolean = false,
executionEnvironment: Option[String] = None,
options: java.util.Map[String, String] = java.util.Collections.emptyMap
): PolyglotContext = {
executionEnvironment.foreach { name =>
options.put("enso.ExecutionEnvironment", name)
}
val context = Context
.newBuilder()
.allowExperimentalOptions(true)
Expand Down
20 changes: 18 additions & 2 deletions engine/runner/src/main/scala/org/enso/runner/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ object Main {
private val AUTH_TOKEN = "auth-token"
private val AUTO_PARALLELISM_OPTION = "with-auto-parallelism"
private val SKIP_GRAALVM_UPDATER = "skip-graalvm-updater"
private val EXECUTION_ENVIRONMENT_OPTION = "execution-environment"

private lazy val logger = Logger[Main.type]

Expand Down Expand Up @@ -355,6 +356,16 @@ object Main {
.desc("Skips GraalVM and its components setup during bootstrapping.")
.build

val executionEnvironmentOption = CliOption.builder
.longOpt(EXECUTION_ENVIRONMENT_OPTION)
.hasArg(true)
.numberOfArgs(1)
.argName("name")
.desc(
"Execution environment to use during execution (`live`/`design`). Defaults to `design`."
)
.build()

val options = new Options
options
.addOption(help)
Expand Down Expand Up @@ -396,6 +407,7 @@ object Main {
.addOptionGroup(cacheOptionsGroup)
.addOption(autoParallelism)
.addOption(skipGraalVMUpdater)
.addOption(executionEnvironmentOption)

options
}
Expand Down Expand Up @@ -530,6 +542,7 @@ object Main {
* @param enableIrCaches are IR caches enabled
* @param inspect shall inspect option be enabled
* @param dump shall graphs be sent to the IGV
* @apram executionEnvironment optional name of the execution environment to use during execution
*/
private def run(
path: String,
Expand All @@ -540,7 +553,8 @@ object Main {
enableIrCaches: Boolean,
enableAutoParallelism: Boolean,
inspect: Boolean,
dump: Boolean
dump: Boolean,
executionEnvironment: Option[String]
): Unit = {
val file = new File(path)
if (!file.exists) {
Expand Down Expand Up @@ -580,6 +594,7 @@ object Main {
enableIrCaches,
strictErrors = true,
enableAutoParallelism = enableAutoParallelism,
executionEnvironment = executionEnvironment,
options = options
)
if (projectMode) {
Expand Down Expand Up @@ -1092,7 +1107,8 @@ object Main {
shouldEnableIrCaches(line),
line.hasOption(AUTO_PARALLELISM_OPTION),
line.hasOption(INSPECT_OPTION),
line.hasOption(DUMP_GRAPHS_OPTION)
line.hasOption(DUMP_GRAPHS_OPTION),
Option(line.getOptionValue(EXECUTION_ENVIRONMENT_OPTION))
)
}
if (line.hasOption(REPL_OPTION)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ class BuiltinTypesTest
4
) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.PushContextResponse(contextId)),
TestMessages.update(contextId, idY, ConstantsGen.FUNCTION_BUILTIN),
TestMessages.update(contextId, idY, ConstantsGen.FUNCTION),
TestMessages.update(contextId, idMain, ConstantsGen.INTEGER),
context.executionComplete(contextId)
)
Expand Down Expand Up @@ -319,7 +319,7 @@ class BuiltinTypesTest
3
) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.PushContextResponse(contextId)),
TestMessages.update(contextId, idMain, ConstantsGen.FUNCTION_BUILTIN),
TestMessages.update(contextId, idMain, ConstantsGen.FUNCTION),
context.executionComplete(contextId)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1952,7 +1952,7 @@ class RuntimeServerTest
context.receiveNIgnoreStdLib(5) should contain theSameElementsAs Seq(
Api.Response(Api.BackgroundJobsStartedNotification()),
Api.Response(requestId, Api.PushContextResponse(contextId)),
TestMessages.update(contextId, xId, ConstantsGen.FUNCTION_BUILTIN),
TestMessages.update(contextId, xId, ConstantsGen.FUNCTION),
TestMessages.update(contextId, mainRes, ConstantsGen.NOTHING),
context.executionComplete(contextId)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.node.ProgramRootNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.state.IOPermissions;
import org.enso.interpreter.runtime.state.ExecutionEnvironment;
import org.enso.interpreter.runtime.tag.AvoidIdInstrumentationTag;
import org.enso.interpreter.runtime.tag.IdentifiedTag;
import org.enso.interpreter.runtime.tag.Patchable;
Expand Down Expand Up @@ -320,12 +320,13 @@ private boolean astContainsExprTypes(Tree ast, List<Class<? extends Tree>> exprT
}

@Option(
name = "IOEnvironment",
category = OptionCategory.USER,
help = "The IO environment for program execution.")
public static final OptionKey<IOPermissions> IO_ENVIRONMENT =
new OptionKey<>(
IOPermissions.PRODUCTION, new OptionType<>("IOEnvironment", IOPermissions::forName));
name = "ExecutionEnvironment",
category = OptionCategory.USER,
help = "The environment for program execution. Defaults to `design`.")
public static final OptionKey<ExecutionEnvironment> EXECUTION_ENVIRONMENT =
new OptionKey<>(
ExecutionEnvironment.DESIGN, new OptionType<>("ExecutionEnvironment", ExecutionEnvironment::forName));


private static final OptionDescriptors OPTIONS =
OptionDescriptors.createUnion(
Expand Down
Loading

0 comments on commit 3cce3b3

Please sign in to comment.