[e-lang] Scope / EEnv split

Thomas Leonard tal at it-innovation.soton.ac.uk
Tue Sep 7 06:58:22 PDT 2010


On Mon, 2010-05-24 at 09:50 -0400, Kevin Reid wrote:
> 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.

OK, I've had a go at this. Here are the patches so far:

1. Split Scope into Scope and EEnv, by making EEnv a copy of Scope

EExpr.eval (and EExpr.compile) now take an EEnv instead of a Scope.
evalToPair still takes a Scope, because it's specific to the interpreter
(a compiler probably wouldn't offer this?).

http://gitorious.org/~tal-itinnov/repo-roscidus/it-innovation/commit/e873f8afade0e4c0b3573fc7dc7fd35186161c54

2. Remove unnecessary EEnv/Scope methods

e.g. there's no need for Scope to have a bindings/0 method, and no need
for EEnv to have an EvalContext, etc

http://gitorious.org/~tal-itinnov/repo-roscidus/it-innovation/commit/c506903803b06bde9f3036ff368958d80803d833

3. Re-enabled LiteralSlotNounExpr and LiteralNounExpr optimisations

These weren't used at all, but it appears that the intention was to use
them for DeepFrozen Slots only. I don't understand what the plan was
here, but I switched to using them for all slots in the environment.
Will this cause problems? This means that EvalContext's outers only
needs to contain values defined in the E code, not values from the
environment.

http://gitorious.org/~tal-itinnov/repo-roscidus/it-innovation/commit/bd23c08954a8ea72bc68735ab6ae35948bda5fed

4. Removed ScopeLayout from EEnv

Now, an EEnv is just a map from names to Slots, plus a fqnPrefix.

NounPatterns are generated dynamically in asScope/0: FinalSlots get
FinalPatterns and other slots get SlotPatterns.

Note this causes a slight change:

  def x := 4
  e`x := 5`.eval(safeScope.withSlot("&x", &x))

Before, this gave the run-time error "Final variables may not be changed"
Now, it gives the compile-time error "Can't assign to final variable: x"

http://gitorious.org/~tal-itinnov/repo-roscidus/it-innovation/commit/546d1317ed42c070d4f705da15bf8f1db711062f

5. Added ScopeLayoutEnv, to avoid creating lots of NounPatterns

This layout just holds a reference to the EEnv and creates the Patterns
from that on demand, rather than creating all the patterns at the start.

http://gitorious.org/~tal-itinnov/repo-roscidus/it-innovation/commit/a1dc0b54a3b9519329c7c54def57d766da778319


The overall effect of these changes is that safeScope is now an EEnv,
whose state is simply:

public class EEnv implements EIteratable {
    private final ConstMap myOuters;
    private final String myFqnPrefix;

This means that EEnv's bindings are clearly immutable (unlike Scope,
which is mutable but tries not to let E code see this, leading to the
previously-reported security issue).

It should therefore be safe to give safeScope to E code, without relying
on taming.

This should make the API easier to understand (e.g. it's now clear that
you can't pass locals to EExpr.eval, because EEnv can't contain any).

This is an incompatible change, although most E code won't notice (since
eCode.eval(safeScope) works as before).


TODO:

- Find out the rationale behind ScopeMaker.init vs ScopeMaker.comp.
- Check whether "literal" nouns being non-DeepFrozen is a problem.
- Maybe simplify/change API for EEnv to allow for passing bindings in
future.
- Clean up EEnv API to avoid adding and stripping "&" all over the
place?
- Remove ScopeMaker? It's basically just a FlexList now.

Does this look like a reasonable approach?


-- 
Dr Thomas Leonard
IT Innovation Centre
2 Venture Road
Southampton
Hampshire SO16 7NP

Tel: +44 0 23 8076 0834
Fax: +44 0 23 8076 0833
mailto:tal at it-innovation.soton.ac.uk
http://www.it-innovation.soton.ac.uk 



More information about the e-lang mailing list