-Major tasks:
-------------
+Error Reporting:
+----------------
- Apply the method verification process to indexers and properties as well.
+ * Make yyerror show a nice syntax error, instead of the current mess.
- Properties and 17.6.3: Finish it.
+Iterators
+---------
+ * `yield' is no longer a keyword, it only has special
+ meaning before a return or break keywords.
- Implement pre-processor.
+ * Study side effects with assign
+ * Study TemporaryStorage/LocalStorage -> Merge/rename
-BUGS
-----
+ * Reset should throw not implemented now.
+
+Instance idea
+-------------
-* Currently the code path for 108/109 reporting is not being ran for methods
- as we need to compare method signatures. But since we retrieve the expensive
- method arguments in the method, we probably should do 108/109 processing there.
+ It would be nice to have things that can be "instances" to have an
+ EmitInstance method (this would default to nothing).
-* Emit warning on hiding members without NEW not only in members.
+ The idea is to be able to use efficiently the instance data on stack
+ manipulations, as opposed to the current scheme, where we basically have
+ a few special cases.
-* Implement visibility.
-
-* Adding variables.
+Optimization ideas
+------------------
- We do add variables in a number of places, and this is erroneous:
+ Currently when we build a type cache, it contains private members,
+ internal members, and internal protected members; We should trim
+ these out, as it shows up on the profile.
- void a (int b)
- {
- int b;
- }
+ We create too many Arraylists; When we know the size, we should create
+ an array;
+
+ During parsing we use arraylists to accumulate data, like this:
+
+ thing:
+
+ thing_list
+ : thing { $$ =new ArrayList (); $$.Add ($1); }
+ | thing_list thing { ArrayList a = $1; a.Add ($2); $$ = a; }
+
+ We probably could start using "Pairs" there:
+
+ thing_list
+ : thing { $$ = new Pair ($1, null); }
+ | thing_list thing { Pair p = $1; $$ = new Pair ($2, $1); }
+
+
+Anonymous Methods
+-----------------
+
+ Plan:
+
+ * Resolve anonymous methods before.
+ * Each time a Local matches, if the mode is `InAnonymous', flag
+ the VariableInfo for `proxying'.
+ * During Resolve track the depth required for local variables.
+ * Before Emit, create proxy classes with proper depth.
+ * Emit.
+
+Open question:
+ Create a toplevel block for anonymous methods?
+
+EmitContext.ResolveTypeTree
+---------------------------
+
+ We should investigate its usage. The problem is that by default
+ this will be set when calling FindType, that triggers a more expensive
+ lookup.
+
+ I believe we should pass the current EmitContext (which has this turned off
+ by default) to ResolveType/REsolveTypeExpr and then have the routines that
+ need ResolveType to pass null as the emit context.
+
+DeclareLocal audit
+------------------
+
+ DeclareLocal is used in various statements. The audit should be done
+ in two steps:
+
+ * Identify all the declare locals.
+
+ * Identify its uses.
+
+ * Find if we can make wrapper functions for all of them.
+
+ Then we can move DeclareLocal into a helper class.
+
+ This is required to fix foreach in iterators.
+
+Large project:
+--------------
+
+ Drop FindMembers as our API and instead extract all the data
+ out of a type the first time into our own datastructures, and
+ use that to navigate and search the type instead of the
+ callback based FindMembers.
+
+ Martin has some some of this work with his TypeHandle code
+ that we could use for this.
- Also:
+Notes on memory allocation
+--------------------------
- void a (int b)
- {
- foreach (int b ...)
- ;
+ Outdated:
+
+ A run of the AllocationProfile shows that the compiler allocates roughly
+ 30 megabytes of strings. From those, 20 megabytes come from
+ LookupType.
+
+ See the notes on current_container problems below on memory usage.
+
+LookupTypeReflection:
+---------------------
+
+ With something like `System.Object', LookupTypeReflection will be called
+ twice: once to find out that `System' is not a type and once
+ for System.Object.
+
+ This is required because System.Reflection requires that the type/nested types are
+ not separated by a dot but by a plus sign.
+
+ A nested class would be My+Class (My being the toplevel, Class the nested one).
+
+ It is interesting to look at the most called lookups when bootstrapping MCS:
+
+ 647 LTR: ArrayList
+ 713 LTR: System.Globalization
+ 822 LTR: System.Object+Expression
+ 904 LTR: Mono.CSharp.ArrayList
+ 976 LTR: System.Runtime.CompilerServices
+ 999 LTR: Type
+ 1118 LTR: System.Runtime
+ 1208 LTR: Mono.CSharp.Type
+ 1373 LTR: Mono.Languages
+ 1599 LTR: System.Diagnostics
+ 2036 LTR: System.Text
+ 2302 LTR: System.Reflection.Emit
+ 2515 LTR: System.Collections
+ 4527 LTR: System.Reflection
+ 22273 LTR: Mono.CSharp
+ 24245 LTR: System
+ 27005 LTR: Mono
+
+ Analysis:
+ The top 9 lookups are done for things which are not types.
+
+ Mono.CSharp.Type happens to be a common lookup: the class Type
+ used heavily in the compiler in the default namespace.
+
+ RED FLAG:
+
+ Then `Type' is looked up alone a lot of the time, this happens
+ in parameter declarations and am not entirely sure that this is
+ correct (FindType will pass to LookupInterfaceOrClass a the current_type.FullName,
+ which for some reason is null!). This seems to be a problem with a lost
+ piece of context during FindType.
+
+ System.Object is also used a lot as a toplevel class, and we assume it will
+ have children, we should just shortcut this.
+
+ A cache:
+
+ Adding a cache and adding a catch for `System.Object' to flag that it wont be the
+ root of a hierarchy reduced the MCS bootstrap time from 10.22 seconds to 8.90 seconds.
+
+ This cache is currently enabled with SIMPLE_SPEEDUP in typemanager.cs. Memory consumption
+ went down from 74 megs to 65 megs with this change.
+
+Ideas:
+------
+
+ Instead of the hack that *knows* about System.Object not having any children classes,
+ we should just make it simple for a probe to know that there is no need for it.
+
+The use of DottedName
+---------------------
+
+ We could probably use a different system to represent names, like this:
+
+ class Name {
+ string simplename;
+ Name parent;
}
-* Visibility
+ So `System.ComponentModel' becomes:
+
+ x: (System, null)
+ y: (ComponentModel, x)
+
+ The problem is that we would still need to construct the name to pass to
+ GetType.
+
+ This has been now implemented, its called "QualifiedIdentifier"
- I am not reporting errors on visibility yet.
+current_container/current_namespace and the DeclSpace
+-----------------------------------------------------
-* Interfaces
+ We are storing fully qualified names in the DeclSpace instead of the node,
+ this is because `current_namespace' (Namepsace) is not a DeclSpace like
+ `current_container'.
- For indexers, the output of ix2.cs is different from our
- compiler and theirs. They use a DefaultMemberAttribute, which
- I have yet to figure out:
+ The reason for storing the full names today is this:
- .class interface private abstract auto ansi INTERFACE
- {
- .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string)
- = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item..
- ...
+ namespace X {
+ class Y {
+ }
}
-* Interface indexers
+ namespace A {
+ class Y {
+ }
+ }
- I have not figured out why the Microsoft version puts an
- `instance' attribute, and I am not generating this `instance' attribute.
+ The problem is that we only use the namespace stack to track the "prefix"
+ for typecontainers, but they are not typecontainers themselves, so we have
+ to use fully qualified names, because both A.X and A.Y would be entered
+ in the toplevel type container. If we use the short names, there would be
+ a name clash.
- Explanation: The reason for the `instance' attribute on
- indexers is that indexers only apply to instances
+ To fix this problem, we have to make namespaces DeclSpaces.
-* Handle destructors specially
+ The full size, contrasted with the size that could be stored is:
+ corlib:
+ Size of strings held: 368901
+ Size of strings short: 147863
- Turn ~X () { a () } into:
- void Finalize () { try { a (); } finally { base.Finalize (); } }
+ System:
+ Size of strings held: 212677
+ Size of strings short: 97521
+
+ System.XML:
+ Size of strings held: 128055
+ Size of strings short: 35782
+
+ System.Data:
+ Size of strings held: 117896
+ Size of strings short: 36153
+
+ System.Web:
+ Size of strings held: 194527
+ Size of strings short: 58064
+
+ System.Windows.Forms:
+ Size of strings held: 220495
+ Size of strings short: 64923
+
+
+TODO:
- The code is mostly done, but `base' is missing. The reason it is
- missing is because we have to implement visibility first.
+ 1. Create a "partial" emit context for each TypeContainer..
-* Method Names
+ 2. EmitContext should be partially constructed. No IL Generator.
- Method names could be; `IFACE.NAME' in the method declaration,
- stating that they implement a specific interface method.
+ interface_type review.
- We currently fail to parse it.
+ parameter_array, line 952: `note: must be a single dimension array type'. Validate this
-* Arrays
+Dead Code Elimination bugs:
+---------------------------
- We need to make sure at *compile time* that the arguments in
- the expression list of an array creation are always positive.
+ I should also resolve all the children expressions in Switch, Fixed, Using.
-* Implement dead code elimination in statement.cs
+Major tasks:
+------------
- It is pretty simple to implement dead code elimination in
- if/do/while
+ Pinned and volatile require type modifiers that can not be encoded
+ with Reflection.Emit.
+
+ Properties and 17.6.3: Finish it.
-* Indexer bugs:
+ Implement base indexer access.
- the following wont work:
+readonly variables and ref/out
+
+BUGS
+----
- x [0] = x [1] = N
+* Check for Final when overriding, if the parent is Final, then we cant
+ allow an override.
- if x has indexers, the value of x [N] set is set to void. This needs to be
- fixed.
+* Interface indexers
-* Array declarations
+ I have not figured out why the Microsoft version puts an
+ `instance' attribute, and I am not generating this `instance' attribute.
- Multi-dim arrays are declared as [,] instead of [0..,0..]
+ Explanation: The reason for the `instance' attribute on
+ indexers is that indexers only apply to instances
* Break/Continue statements
They should transfer control to the finally block if inside a try/catch
block.
-* Conversions and overflow
-
- I am not using the checked state while doing type casts,
- they should result in conv.ovf.XXX
-
* Method Registration and error CS111
The way we use the method registration to signal 111 is wrong.
Method registration should only be used to register methodbuilders,
we need an alternate method of checking for duplicates.
-* We need to catch:
-
- extern string Property {
- get { }
- }
-
- The get there should only have a semicolon
-
*
> // CSC sets beforefieldinit
> class X {
PENDING TASKS
-------------
- * Implement Goto.
-
- * Unsafe code.
- Making the parser accept unsafe code.
-
- * Implement `base' (BaseAccess class)
-
- * Implement constant folding. We might need to implement
- a new `Constant' class and derive Literal from it.
-
-* OUT Variables passed as OUT variables.
-
- Currently we pass the pointer to the pointer (see expression.cs:Argument.Emit)
-
-* Function Declarations
-
- Support PINvoke/Internallcall and extern declarated-functions.
-
-* Manual field layout in structures
-
-* Make the rules for inheritance/overriding apply to
- properties, operators and indexers (currently we only do this
- on methods).
+* Merge test 89 and test-34
-* Handle volatile
-
-* Support Re-Throw exceptions:
-
- try {
- X ();
- } catch (SomeException e){
- LogIt ();
- throw;
- }
-
-* Static flow analysis
-
- Required to warn about reachability of code and definite
- assignemt as well as missing returns on functions.
-
-* Implement `goto case expr'
-
- switch (x){
- case 1: print ("1"); goto case 4;
- case 2: ...
- case 4: ...
- }
+* Revisit
+ Primary-expression, as it has now been split into
+ non-array-creation-expression and array-creation-expression.
+
* Code cleanup
The information when registering a method in InternalParameters
is duplicated, you can always get the types from the InternalParameters
-OPTIMIZATIONS
--------------
+* Emit modreq for volatiles
-* Emitcontext
+ Handle modreq from public apis.
- Do we really need to instanciate this variable all the time?
+* Emit `pinned' for pinned local variables.
- It could be static for all we care, and just use it for making
- sure that there are no recursive invocations on it.
+ Both `modreq' and pinned will require special hacks in the compiler.
-* Static-ization
+* Make sure that we are pinning the right variable
- Since AppDomain exists, maybe we can get rid of all the stuff
- that is part of the `compiler instance' and just use globals
- everywhere.
+* Merge tree.cs, rootcontext.cs
+OPTIMIZATIONS
+-------------
-* Constructors
+* User Defined Conversions is doing way too many calls to do union sets that are not needed
- Currently it calls the parent constructor before initializing fields.
- It should do it the other way around.
+* Add test case for destructors
-* Reducer and -Literal
+* Places that use `Ldelema' are basically places where I will be
+ initializing a value type. I could apply an optimization to
+ disable the implicit local temporary from being created (by using
+ the method in New).
- Maybe we should never handle -Literal in Unary expressions and let
- the reducer take care of it always?
+* Dropping TypeContainer as an argument to EmitContext
-* Use of EmitBranchable
+ My theory is that I can get rid of the TypeBuilder completely from
+ the EmitContext, and have typecasts where it is used (from
+ DeclSpace to where it matters).
- Currently I use brfalse/brtrue in the code for statements, instead of
- using the EmitBranchable function that lives in Binary
+ The only pending problem is that the code that implements Aliases
+ is on TypeContainer, and probably should go in DeclSpace.
-* Create an UnimplementedExpcetion
+* Use of local temporary in UnaryMutator
- And use that instead of plain Exceptions to flag compiler errors.
+ We should get rid of the Localtemporary there for some cases
-* ConvertImplicit
+ This turns out to be very complex, at least for the post-version,
+ because this case:
- Currently ConvertImplicit will not catch things like:
+ a = i++
- - IntLiteral in a float context to generate a -FloatLiteral.
- Instead it will perform an integer load followed by a conversion.
+ To produce optimal code, it is necessary for UnaryMutator to know
+ that it is being assigned to a variable (the way the stack is laid
+ out using dup requires the store to happen inside UnaryMutator).
* Tests
Write tests for the various reference conversions. We have
test for all the numeric conversions.
-* Remove the tree dumper, cleanup `public readonly'
-
- And make all the stuff which is `public readonly' be private unless
- required.
-
* Optimizations
In Indexers and Properties, probably support an EmitWithDup
in the stack, so that later a Store can be emitted using that
this pointer (consider Property++ or Indexer++)
-
* Optimizations: variable allocation.
When local variables of a type are required, we should request
* Add a cache for the various GetArrayMethod operations.
-* Optimization:
-
- Do not use StatementCollections, use ArrayLists of Statements,
- and then "copy" it out to arrays. Then reuse the existing
- Statement structures.
+* MakeUnionSet Callers
-* TypeManager.FindMembers:
+ If the types are the same, there is no need to compute the unionset,
+ we can just use the list from one of the types.
- Instead of having hundreds of builder_to_blah hash table, have
- a single one that maps a TypeBuilder `t' to a set of classes
- that implement an interface that supports FindMembers.
+* Factor the lookup code for class declarations an interfaces
+ (interface.cs:GetInterfaceByName)
RECOMMENDATIONS
---------------
Not sure that this grammar is correct, we might have to
resolve this during semantic analysis.
-
-* Try/Catch
-
- Investigate what is the right value to return from `Emit' in
- there (ie, for the `all code paths return')
-
-
-* Optimizations
-
- Only create one `This' instance per class, and reuse it.
-
- Maybe keep a pool of constants/literals (zero, 1)?
-
-************
-Potential bug:
-
- We would need to decode the shortname before we lookup members?
-
- Maybe not.
-
-interface I {
- void A ();
-}
-
-class X : I {
- void I.A ();
-}
-
-class Y : X, I {
- void I.A () {}
-}
\ No newline at end of file