As many of us know ncc generates an "unused parameter" every time it sees "_":
eg.
def f(_,_)
..
def g(_,_)
..
in assembly it looks like:
.method f(_N_5,_N_6)
..
.method f(_N_8,_N_96)
..
Metadata grows. Strings in metadata are pointed by offset. In this
example we have 4 strings in metadata's heap, and 4 offsets in
methods' signatures.
let say, if we would change generated code to:
.method f(_N_0,_N_1)
..
.method f(_N_0,_N_1)
..
We would have two strings in metadata's heap (instead of four).
This simple observation points me to:
Index: ncc/generation/Typer3.n
===================================================================
--- ncc/generation/Typer3.n (revision 8214)
+++ ncc/generation/Typer3.n (working copy)
@@ -1913,8 +1913,14 @@
EmitCall (loc : Location, ret_type : TyVar, func : TExpr, parms :
list [Parm], is_tail : bool) : TExpr
{
+ mutable i = 1;
foreach (p in parms)
+ {
+ when (p.name.Contains("_N_"))
+ p.name = "_N_" + i.ToString();
p.expr = Walk (p.expr);
+ i++;
+ }
def just_call (meth, func, clo_parms) {
def (parms, ini) = TupleParms (meth.GetHeader (), parms,
clo_parms.Length);
Index: ncc/generation/HierarchyEmitter.n
===================================================================
--- ncc/generation/HierarchyEmitter.n (revision 8214)
+++ ncc/generation/HierarchyEmitter.n (working copy)
@@ -984,8 +984,14 @@
match (parms) {
| [] => ()
| (p : Fun_parm) :: ps =>
- p.builder = GetMethodInfo ().DefineParameter (pos,
parameter_attributes (p), p.name);
+ def packedname =
+ if (p.name.Contains("_N_"))
+ "_N_" + pos.ToString()
+ else
+ p.name;
+ p.builder = GetMethodInfo ().DefineParameter (pos,
parameter_attributes (p), packedname);
+
match (p.default_value) {
| Some (TExpr.Literal (lit)) => p.builder.SetConstant
(lit.AsObject (InternalType));
| Some (e) => Util.ice ($"complex expr $e");
Index: ncc/typing/TypedTree.n
===================================================================
--- ncc/typing/TypedTree.n (revision 8214)
+++ ncc/typing/TypedTree.n (working copy)
@@ -1359,7 +1359,7 @@
{
public kind : ParmKind;
public mutable expr : TExpr;
- public name : string; // "" if no name given
+ public mutable name : string; // "" if no name given
public mutable required_type : TyVar;
public this (expr : TExpr)
Which gives... about 14kb of saved generated file size (for
Nemerle.Compiler.dll). Yes, it's "only" 2% but I think it's worth
considering anyway.
This patch is a hack, if someone would point me to better place to do
such things.....This should be done right after parsing a method
header.
Local values are safe - compiled assembly contains no information
about their names.
Take care,
--
Paweł Różański
There might be a better way to check if parameter was used, though I'm
not sure it is really stored in Parm object.
>
Good idea, if you could do it without resolving to Contains("_N_") it
would be great (I know, probably this kind of checking slipped
somewhere else in the code, but it's not that nice).
> Local values are safe - compiled assembly contains no information
> about their names.
>
> Take care,
> --
> Paweł Różański
>
> >
>
--
Kamil Skalski
http://kamil-skalski.pl