Reference

std/sandbox/lib

std/sandbox/src/lib.trb

Loads .trb files as sandboxed receiver closures - the mechanism behind project.trb and configuration scripts (see "Receiver Scripts and the Sandbox" in CONCEPT.md, and docs/design/SCRIPTS.md).

A script runs in the VM, always: the step and time limits and the panic that does not end the caller are properties of an interpreter (docs/design/SCRIPTS.md section 1). A program torb run runs in the VM loads one, from a path it was compiled with or from any other, and so does a native binary torb build --embed-vm built, which embeds the VM. A native binary torb build compiled loads one through the front end and the VM it embeds (slice 8): the script is checked against Value and run in that VM, and the value crosses as text in both directions, through the derived Encode and Decode of Value, every field included - so a receiver of such a program is Encode & Decode, which a type of plain settings is by derivation.

type SandboxError

type SandboxError with Show, Error

What went wrong loading a script: a syntax or type error against the receiver type, or a capability it does not have. line is 0 when the problem is not about one place in the script (e.g. the file could not be read).

field line

line: Int

0 when the problem is not about one place in the script, such as the file not being readable at all.

field message

message: String

What went wrong, without the line number.

fn show

fn show(): String

"{line}: {message}", or just message when there is no line.

extend Int64

extend Int64

The byte unit SandboxCapabilities.limits is written in.

fn megabytes

fn megabytes(): Int64

Bytes, for SandboxCapabilities.limits: 64.megabytes().

type SandboxCapabilities

type SandboxCapabilities

What a script may do, granted at the call site of Sandbox.load - never in the script or its project file (a script that could grant itself capabilities would not be a sandbox). Left at the defaults, a script has no IO, no network, no clock, no environment and no foreign functions.

field moduleNames

protected var moduleNames: List<String> = []

The modules SandboxCapabilities.modules granted, which the script's imports are held against.

field readOnlyRoots

protected var readOnlyRoots: List<String> = []

Not documented.

field readWriteRoots

protected var readWriteRoots: List<String> = []

Not documented.

field variablePatterns

protected var variablePatterns: List<String> = []

Not documented.

field stepLimit

protected var stepLimit: Int = 1_000_000

Not documented.

field memoryLimit

protected var memoryLimit: Int = 64_000_000

Not documented.

field timeLimit

protected var timeLimit: Int = 2000

Milliseconds: a Duration is no constant a default could be.

field workerLimit

protected var workerLimit: Int = 1

Not documented.

fn modules

var fn modules(...names: String)

Additional parts of the standard library the script may use, e.g. "std/text".

fn files

var fn files(readOnly: String = "", readWrite: String = "")

File system roots the script may reach. A side that is left out stays closed.

fn environment

var fn environment(...patterns: String)

Environment variable name patterns the script may read, e.g. "APP_*".

fn limits

var fn limits(steps: Int = 1_000_000, memory: Int = 64.megabytes(), time: Duration = 2.seconds(), workers: Int = 1)

Guards against runaway scripts (loop {}). workers is the most workers the script's tasks may run on at once (docs/design/CONCURRENCY.md section 3): a script that could fan out over the host's cores would be a denial of service its grant does not show. The VM runs the tasks of a script on the thread of its sandbox, so a script never uses more than one whatever the number says.

type Script

type Script<Value>

A loaded script, ready to run against a Value of the caller's own. It is not a closure, because the body of the script runs inside the sandbox and can still fail there: a step, memory or time limit, or a panic - the only panic in the language that is recoverable, because the VM is interpreting it and the script has a heap of its own.

fn apply

fn apply(var value: Value): Result<Void, SandboxError>

Runs the body of the script against value, configuring it in place.

type Sandbox

native type Sandbox

Sandboxes and type checks .trb files against a receiver type.

fn load

static fn load<Value>(path: String, capabilities: (var self: SandboxCapabilities) => Void = {}): Result<Script<Value>, SandboxError>

Type checks path against Value and returns it as a Script, ready to run against a Value of the caller's own. What is wrong with the file (syntax, types, a module the script may not import) is reported here; what goes wrong while it runs is reported by Script.apply instead. The trailing block grants capabilities beyond the defaults.

A path the program was compiled with - a literal of a Sandbox.load - names a script the program carries, which torb check checked with it. Any other path is read, checked against Value and lowered when the program asks for it, relative to the working directory (docs/design/SCRIPTS.md slice 7); Value is then a type without type arguments.

Examples

type ServerConfig {
  var port: Int = 8080
}

const loaded = Sandbox.load<ServerConfig>("./config.trb") {
  files readOnly: "./config"
  limits steps: 1_000_000, memory: 16.megabytes()
}
print loaded.isOk()