[svn] r6007: nemerle/trunk/ncc: generation/Typer3.n
hierarchy/ClassMembers.n testsuite/negative/yield2.n t...
malekith
svnadmin at nemerle.org
Thu Dec 15 13:13:41 CET 2005
Log:
Move most of yield-handling to T3.
Author: malekith
Date: Thu Dec 15 13:13:39 2005
New Revision: 6007
Modified:
nemerle/trunk/ncc/generation/Typer3.n
nemerle/trunk/ncc/hierarchy/ClassMembers.n
nemerle/trunk/ncc/testsuite/negative/yield2.n
nemerle/trunk/ncc/testsuite/positive/yield.n
nemerle/trunk/ncc/typing/LocalValue.n
nemerle/trunk/ncc/typing/Typer.n
nemerle/trunk/ncc/typing/Typer2.n
Modified: nemerle/trunk/ncc/generation/Typer3.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer3.n (original)
+++ nemerle/trunk/ncc/generation/Typer3.n Thu Dec 15 13:13:39 2005
@@ -428,7 +428,11 @@
/** Return code referencing closure of [hd]. */
ClosureRef (hd : Fun_header) : TExpr
{
- if (hd.id == current_method.id) {
+ if (current_method.name == "_N_yielding_function") {
+ Util.cassert (hd.id == current_method.id ||
+ current_method.decl.DefinedIn.id == hd.id);
+ TExpr.This (local_function_type.GetMemType ())
+ } else if (hd.id == current_method.id) {
PlainRef (current_closure)
} else if (hd.usage == FunctionUsage.UsedJustOnce) {
ClosureRef (hd.decl.DefinedIn)
@@ -655,6 +659,57 @@
}
+ PrepareEnumeratorObject () : Parsetree.ClassMember
+ {
+ def yield_type = Option.UnSome (the_method.yield_stuff) [0];
+
+ <[ decl:
+ class $(Macros.NewSymbol ("Enumerator") : name) :
+ System.Collections.IEnumerator,
+ System.Collections.Generic.IEnumerator [$yield_type]
+ {
+ public Current : $yield_type
+ {
+ get { this._N_current }
+ }
+
+ public Dispose () : void
+ {
+ this._N_state = -1;
+ }
+
+ public Reset () : void
+ {
+ throw System.NotSupportedException ();
+ }
+
+ public MoveNext () : bool
+ {
+ }
+ }
+ ]>
+ }
+
+
+ SetEnumeratorBody (clo_type : TypeInfo, subst : Subst) : void
+ {
+ match (current_local_fun.body) {
+ | FunBody.Typed (DefValIn (_, _, DefValIn (_, _, DefFunctionsIn ([fh], _)))) =>
+ def meth = SingleMemberLookup (clo_type, "MoveNext") :> MethodBuilder;
+ fh.used_closures = fh.GetParents ();
+ PrepareForEmission (meth, fh, subst);
+ def child = Typer3 (this, meth);
+ child.current_subst = subst;
+ child.Run ();
+
+ current_local_fun.body = FunBody.Typed (PlainRef (current_closure));
+
+ | FunBody.Typed (t)
+ | _ with t = null => Util.ice ($ "oops, t=$t")
+ }
+ }
+
+
PrepareClosure () : list [TExpr]
{
//Message.Debug ($"closure for $(current_local_fun.name) $(current_local_fun.closure_vars)");
@@ -671,12 +726,17 @@
subst.Apply (t.DeepFix ())
}
- def clo_type = CurrentType.DefineNestedType (<[ decl:
+ def clo_decl =
+ if (the_method.yield_stuff.IsNone)
+ <[ decl:
private sealed class $(Macros.NewSymbol ("closure") : name)
{
internal this () {}
}
- ]>, do_fixup = false);
+ ]>
+ else PrepareEnumeratorObject ();
+
+ def clo_type = CurrentType.DefineNestedType (clo_decl, do_fixup = false);
clo_type.forced_typarms = new_tp;
clo_type.FixupDefinedClass ();
@@ -704,7 +764,10 @@
});
foreach (decl in vars) {
- def name = Macros.NewSymbol (decl.Name);
+ def name =
+ if (decl.Name == "_N_current" || decl.Name == "_N_state")
+ Parsetree.Name (decl.Name)
+ else Macros.NewSymbol (decl.Name);
//Message.Debug ($"clo field: $name $(fix_type (decl.Type)) tv=$new_tp");
def ptdecl = <[ decl:
internal mutable
@@ -722,6 +785,9 @@
clo_type.HasBeenUsed = true;
clo_type.Compile ();
+ when (the_method.yield_stuff.IsSome)
+ SetEnumeratorBody (clo_type, subst);
+
[TExpr.DefValIn (InternalType.Void, closure_val, ctor_call, null)]
}
}
Modified: nemerle/trunk/ncc/hierarchy/ClassMembers.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/ClassMembers.n (original)
+++ nemerle/trunk/ncc/hierarchy/ClassMembers.n Thu Dec 15 13:13:39 2005
@@ -598,7 +598,7 @@
internal mutable overridden_method : IMethod;
- internal yield_stuff : option [PT.PExpr * list [PT.Fun_parm]] = None ();
+ internal mutable yield_stuff : option [PT.PExpr * list [PT.Fun_parm]] = None ();
is_var_args : bool;
Modified: nemerle/trunk/ncc/testsuite/negative/yield2.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/yield2.n (original)
+++ nemerle/trunk/ncc/testsuite/negative/yield2.n Thu Dec 15 13:13:39 2005
@@ -4,6 +4,6 @@
{
public GetEnumerator () : IEnumerator [int]
{
- yield "foo"; // E: expected int, got string in assigned value
+ yield "foo"; // E: expected int.*, got string in assigned value
}
}
Modified: nemerle/trunk/ncc/testsuite/positive/yield.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/yield.n (original)
+++ nemerle/trunk/ncc/testsuite/positive/yield.n Thu Dec 15 13:13:39 2005
@@ -26,7 +26,7 @@
do_get (qux : int) : IEnumerator [string]
{
- // yield qux.ToString ();
+ yield qux.ToString ();
yield ene;
yield this.due;
yield rabe;
@@ -55,9 +55,11 @@
42
13
77
+4
raz
dwa
trzy
+5
raz
dwa
trzy
Modified: nemerle/trunk/ncc/typing/LocalValue.n
==============================================================================
--- nemerle/trunk/ncc/typing/LocalValue.n (original)
+++ nemerle/trunk/ncc/typing/LocalValue.n Thu Dec 15 13:13:39 2005
@@ -54,6 +54,9 @@
mutable is_registered : bool;
mutable closure_field : IField;
+ [Accessor (flags = WantSetter | Internal)]
+ mutable never_closurise : bool;
+
[Nemerle.OverrideObjectEquals]
public Equals (other : LocalValue) : bool {
id == other.id
Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n (original)
+++ nemerle/trunk/ncc/typing/Typer.n Thu Dec 15 13:13:39 2005
@@ -80,6 +80,7 @@
solver = Passes.Solver;
current_type = m.DeclaringType;
yield_stuff = m.yield_stuff;
+ m.yield_stuff = None ();
parent_typer = None ();
env = current_type.GlobalEnv;
current_fun = m.GetHeader ();
@@ -87,10 +88,6 @@
messenger = solver.CurrentMessenger;
locals_stack = Stack ();
- inside_yielding_function =
- m.Name == "MoveNext" &&
- current_type.LookupMember ("_N_current") is [_];
-
local_context = LocalContext.Empty;
assert (solver.IsTopLevel);
@@ -150,10 +147,12 @@
Util.ice ($"hidden errors compiling $m");
| _ is SwitchToYielding =>
+ m.yield_stuff = yield_stuff;
def errcnt = Message.ErrorCount;
// just in case
put_in_error_mode ();
m.Body = MakeEnumeratorClass (m.Body);
+ inside_yielding_function = true;
when (errcnt == Message.ErrorCount)
RunTyper ();
when (errcnt == Message.ErrorCount) {
@@ -201,6 +200,7 @@
is_method = parent.is_method;
is_instance_ctor = parent.is_instance_ctor;
env = parent.env;
+ inside_yielding_function = parent.inside_yielding_function;
messenger = parent.messenger;
locals_stack = Stack ();
@@ -295,17 +295,18 @@
| FunBody.Typed =>
Util.ice ($"$(current_fun.body)")
}
- }
-
- RunSecondPass (meth : MethodBuilder) : void
- {
- when (inside_yielding_function)
+ when (inside_yielding_function &&
+ current_fun.name == "_N_yielding_function")
match (current_fun.body) {
| FunBody.Typed (t) => AddYieldStateMachine (t)
| _ => Util.ice ()
}
+ }
+
+ RunSecondPass (meth : MethodBuilder) : void
+ {
def t2 = Typer2 (current_type, meth);
t2.Run ();
def t3 = Typer3 (meth);
@@ -1409,9 +1410,7 @@
| PT.PExpr.This =>
- if (inside_yielding_function)
- TypeExpr (<[ $(This () : typed)._N_this ]>, expected)
- else if (is_method) {
+ if (is_method) {
_ = Expect (expected, current_type.GetMemType (), "`this'");
This ()
} else
@@ -2366,20 +2365,15 @@
match (expr) {
// FIXME | PT.PExpr.ToComplete
| PT.PExpr.Ref (name) when is_method =>
- def th () {
- if (inside_yielding_function) TypeExpr (<[ this ]>)
- else This ()
- }
-
def res =
try {
solver.PushState ();
- Option.UnSome (TypeMember (th (), name.Id, expected));
+ Option.UnSome (TypeMember (This (), name.Id, expected));
} finally {
solver.PopState ();
}
if (res.IsEmpty) []
- else Option.UnSome (TypeMember (th (), name.Id, expected))
+ else Option.UnSome (TypeMember (This (), name.Id, expected))
| _ => []
};
@@ -3050,28 +3044,18 @@
#region yield handling
MakeEnumeratorClass (body : PT.PExpr) : PT.PExpr
{
- def (yield_type, parms) = GetYieldStuff ();
- def this_type = Util.ExprOfQid (current_type.FullName);
- def all_parms = <[ parameter: _N_this : $this_type ]> :: parms;
+ def (yield_type, _) = GetYieldStuff ();
- def pt = <[ decl:
- class $(Macros.NewSymbol ("Enumerator") : name) :
- System.Collections.IEnumerator,
- System.Collections.Generic.IEnumerator [$yield_type]
- {
- mutable _N_current : $yield_type;
- mutable _N_state : int;
-
- public Current : $yield_type
- {
- get { _N_current }
- }
+ def new_body =
+ <[
+ mutable _N_current = Nemerle.Extensions.DefaultValue ($yield_type);
+ mutable _N_state = 0;
- public MoveNext () : bool
+ def _N_yielding_function () : bool
{
_N_MoveNext_exit : {
- // AddYieldStateMachine will add something here, and change -42 to _N_state
- match (-42) {
+ // AddYieldStateMachine will add something here
+ match (_N_state) {
| 0 => {}
| _ => _N_MoveNext_exit (false)
}
@@ -3082,43 +3066,11 @@
}
}
- public Dispose () : void
- {
- _N_state = -1;
- }
-
- public Reset () : void
- {
- throw System.NotSupportedException ();
- }
-
- public this (.. $all_parms)
- {
- }
- }
+ _ = _N_yielding_function;
+ null
]>;
- def tb = current_type.DefineNestedType (pt);
-
- def ctor_assigns =
- all_parms.Map (fun (fp) {
- when (fp.ty is <[ ref $_ ]> || fp.ty is <[ out $_ ]>)
- ReportError (messenger,
- "ref/out parameters not allowed in functions "
- "using ``yield''");
- tb.Define (<[ decl: mutable $(fp.name) : $(fp.ty) ]>);
- <[ this . $(fp.name) = $(fp.name.GetName () : name) ]>
- });
-
- def meth = Typer3.SingleMemberLookup (tb, ".ctor") :> MethodBuilder;
- meth.Body = <[ { .. $ctor_assigns } ]>;
-
- tb.Compile ();
-
- def parm_refs =
- <[ this ]> :: parms.Map (fun (fp) { <[ $(fp.name.GetName () : name) ]> });
-
- <[ $(Util.ExprOfQid (tb.FullName)) (.. $parm_refs) ]>
+ new_body
}
@@ -3134,7 +3086,7 @@
$ "yield used in a function returning "
"$(current_fun.ret_type) (it "
"should be System.Collections.Generic."
- "IEnumerable[T])");
+ "IEnumerator[T])");
(<[ object ]>, [])
}
}
@@ -3151,8 +3103,8 @@
TypeExpr (<[
{
- $(This () : typed) . _N_current = $expr;
- $(This () : typed) . _N_state = $(state_no : int);
+ _N_current = $expr;
+ _N_state = $(state_no : int);
_N_MoveNext_exit (true);
$(label : typed)
}
@@ -3170,9 +3122,7 @@
def yes = TExpr.Literal (InternalType.Boolean, Literal.Bool (true));
Match_case ([(cntpat, yes, [])], TExpr.Goto (m.Type, id, 1), false)
});
- def state =
- TypeExpr (<[ $(This () : typed)._N_state ]>, InternalType.Int32);
- s.e1 = TExpr.Match (m.Type, state, cases + m.cases)
+ s.e1 = TExpr.Match (m.Type, m.expr, cases + m.cases)
| _ => Util.ice ($ "e = $e")
}
}
Modified: nemerle/trunk/ncc/typing/Typer2.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer2.n (original)
+++ nemerle/trunk/ncc/typing/Typer2.n Thu Dec 15 13:13:39 2005
@@ -40,8 +40,10 @@
top_level_fun : MethodBuilder;
mutable this_ptr_decl : LocalValue;
mutable current_fun : Fun_header;
+ top_fun : Fun_header;
current_type : TypeBuilder;
messenger : Messenger;
+ inside_yielding_function : bool;
[System.Flags]
enum Context {
@@ -63,11 +65,14 @@
public this (ty : TypeBuilder, fn : MethodBuilder)
{
current_fun = fn.GetHeader ();
+ top_fun = current_fun;
current_fun.usage = FunctionUsage.Used;
top_level_fun = fn;
current_type = ty;
messenger = Passes.Solver.CurrentMessenger;
+
+ inside_yielding_function = fn.yield_stuff.IsSome;
}
@@ -391,10 +396,12 @@
}
loop (current_fun.parms);
+ // move closure vars of loops to their parent function
foreach (v in locals)
match (v.ValKind) {
| LocalValue.Kind.Function (h, _) =>
- when (h.usage == FunctionUsage.UsedJustOnce)
+ when (h.usage == FunctionUsage.UsedJustOnce ||
+ (inside_yielding_function && top_fun.id == current_fun.id))
if (h.typarms is []) {
current_fun.closure_vars += h.closure_vars;
h.closure_vars = [];
@@ -405,7 +412,10 @@
}
foreach (v in locals) {
- mutable in_clo = false;
+ // FIXME: this is wrong (performance problems) if we're inside
+ // some real local function in yielding function
+ mutable in_clo =
+ inside_yielding_function && !v.NeverClosurise;
v.UsedIn.Iter (fun (h : Fun_header) {
unless (in_clo) {
@@ -687,6 +697,7 @@
LocalValue (current_fun, expr.jump_out.Name,
expected, LocalValue.Kind.Plain (),
is_mutable = true);
+ result.NeverClosurise = true;
def label_id = Util.next_id ();
def ret =
More information about the svn
mailing list