[e-lang] E patches for review: ELoader, seedVat
Kevin Reid
kpreid at switchb.org
Mon May 24 06:50:57 PDT 2010
On May 21, 2010, at 9:22, Thomas Leonard wrote:
> Here, the Scope type fills both roles ("scope" and "newScope"). Some
> safej rules prevent E programs from accessing "internal" details (e.g.
> locals[]). This means you can't write the interpreter in E (using
> Scope), because E can't access these bits even when it needs them.
>
> If they were separate types ("Map env/Scope scope" rather than "Scope
> scope/Scope newScope"), the safej restrictions could go away and
> normal
> capability rules would apply (if you have a Scope, you can call all
> its
> methods, whether you're E or Java).
It's perfectly all right for an interpreter to have a private
environment-with-extra-useful-bits type, but it should not be named
Scope. And the public environment type cannot be a Map because it has
additional metadata, as previously discussed.
I agree that it would be useful not to require safej for what-is-
currently-known-as-Scope. The proper answer is to as you suggest make
it a separate type, but that should not be known as Scope. Perhaps
'EvalEnv' would be a good name.
> Good point. Still, it *is* mutating the slot, even if you can't see
> it.
> Is that a problem? BootRefHandler does this:
>
> if (Ref.isDeepPassByCopy(arg) /* implicit "and is thread-safe" */) {
> return arg;
> }
>
> An E object which forces a LazyEvalSlot (even a DeepFrozen one like
> require) still isn't thread-safe.
This is a confusion in the E-on-Java implementation. Thread-safety is
a separate issue which must be separately flagged; DeepPassByCopy is
necessary (because mutable state and objects with Selfish identities
should not be shared between vats) but not sufficient.
> OK, so the problem is:
>
> - we want to know the guard (reliably)
> - we want to allow custom slots
> - we don't trust custom slots to enforce their claimed guard
>
> Perhaps we could wrap wacky slots in a known wrapper? e.g.
>
> def &myVar := makeGuardedSlot(myWackySlot)
>
> Where makeGuardedSlot would call myWackySlot.getGuard and store a copy
> of the guard. GuardedSlot would check the value against the guard
> every
> time you called get().
>
> An auditor could see that the slot was a GuardedSlot, and thus trust
> it
> to ensure the values it returned always conformed to the guard. But
> for
> the common case (FinalSlot) it would work fine anyway without
> wrapping.
It's not that 'we want to know the guard': it's that we want to know
an arbitrary amount of information about the slot. The binding-based
system allows that to be done -- it makes no assumptions about, for
example, whether the auditor cares about whether the slot is mutable.
There is no fixed list of approved slot types (in your proposal,
FinalSlot and GuardedSlot) which auditors get information about.
Your proposal also requires that the audited code use special slot
types explicitly. Bindings complicate the underlying semantics, but
they are a clearly separated layer from the slots the program is using
for its own purposes.
>> Could you explain the entire object graph leading up to makeTraceln?
>
> <this> is an ELoader, created by makeELoader. It holds a reference to
> makeTraceln and creates traceln instances by combining a prefix with
> the
> filename. Like this:
>
> ? def makeELoader := <elang:interp.ELoaderAuthor>(makeTraceln)
> ? def <libfoo> := makeELoader(dir, [].asMap(), "libfoo$")
>
> Any emaker loaded by libfoo gets a traceln that logs things from
> "libfoo
> $...".
>
> Having <libfoo> should not allow unrestricted access to makeTraceln.
>
>> I suspect a violation of the principle that any object with private
>> state must use an amplified uncall rather than __optUncall/0.
>
> Exactly. The question is whether to amplify using the persistence
> sealer
> or something else.
Ah. Your question is not 'how to uncall makeTraceln' but 'how to
uncall the loader'. And the answer is to use 'something else'.
Since makeELoader gives authority to log with arbitrary prefixes, it
should not be exposed: so loader objects, i.e. <this> must not use
__optUncall but rather some amplifier.
The role to be filled loader/uncaller pair which gives access to
"process authorities" such as makeTraceln and <file> objects, allowing
them to be passed between vats... but shouldn't the usual set,
[<unsafe>, <file>, ...] suffice for that? Maybe we need something
extensible in that set (i.e. an unsealer amplifier with a public
sealer) so that your ELoaders can be uncalled by that?
--
Kevin Reid <http://switchb.org/kpreid/>
More information about the e-lang
mailing list