/// </summary>
public bool InTry;
+ /// <summary>
+ /// Whether we are inside an iterator block.
+ /// </summary>
+ public bool InIterator;
+
+ /// <summary>
+ /// Whether remapping of locals, parameters and fields is turned on.
+ /// Used by iterators and anonymous methods.
+ /// </summary>
+ public bool RemapToProxy;
+
/// <summary>
/// Whether we are in a Catch block
/// </summary>
/// </summary>
public bool InUnsafe;
+ /// <summary>
+ /// Whether we are inside an anonymous method.
+ /// </summary>
+ public bool InAnonymousMethod;
+
/// <summary>
/// Location for this EmitContext
/// </summary>
ConstantCheckState = true;
IsStatic = (code_flags & Modifiers.STATIC) != 0;
+ InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0;
+ RemapToProxy = InIterator;
ReturnType = return_type;
IsConstructor = is_constructor;
CurrentBlock = null;
CurrentFile = loc.File;
if (block != null){
- try {
+ try {
int errors = Report.Errors;
block.EmitMeta (this, block);
block.UsageWarning ();
}
}
- } catch {
+ } catch {
Console.WriteLine ("Exception caught by the compiler while compiling:");
Console.WriteLine (" Block that caused the problem begin at: " + loc);
- Console.WriteLine (" Block being compiled: [{0},{1}]",
- CurrentBlock.StartLocation, CurrentBlock.EndLocation);
+
+ if (CurrentBlock != null){
+ Console.WriteLine (" Block being compiled: [{0},{1}]",
+ CurrentBlock.StartLocation, CurrentBlock.EndLocation);
+ }
throw;
- }
+ }
}
if (ReturnType != null && !has_ret){
// correctly and emit an error instead of a warning.
//
//
- Report.Error (161, loc, "Not all code paths return a value");
- return;
+ if (!InIterator){
+ Report.Error (161, loc, "Not all code paths return a value");
+ return;
+ }
}
if (HasReturnLabel)
ig.Emit (OpCodes.Ret);
} else {
if (!InTry){
+ if (InIterator)
+ has_ret = true;
+
if (!has_ret || HasReturnLabel)
ig.Emit (OpCodes.Ret);
}
return return_value;
}
+ //
+ // Creates a field `name' with the type `t' on the proxy class
+ //
+ public FieldBuilder MapVariable (string name, Type t)
+ {
+ if (InIterator){
+ return IteratorHandler.Current.MapVariable (name, t);
+ }
+
+ throw new Exception ("MapVariable for an unknown state");
+ }
+
+ //
+ // Emits the proper object to address fields on a remapped
+ // variable/parameter to field in anonymous-method/iterator proxy classes.
+ //
+ public void EmitThis ()
+ {
+ ig.Emit (OpCodes.Ldarg_0);
+
+ if (!IsStatic){
+ if (InIterator)
+ ig.Emit (OpCodes.Ldfld, IteratorHandler.Current.this_field);
+ else
+ throw new Exception ("EmitThis for an unknown state");
+ }
+ }
+
/// <summary>
/// A dynamic This that is shared by all variables in a emitcontext.
/// Created on demand.