[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