else
ig.Emit (OpCodes.Clt);
- ig.Emit (OpCodes.Ldc_I4_1);
+ ig.Emit (OpCodes.Ldc_I4_0);
- opcode = OpCodes.Sub;
+ opcode = OpCodes.Ceq;
break;
case Operator.BitwiseOr:
is_base = true;
Expression old = expr;
-
+
expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
if (expr == null)
return null;
ig.Emit (OpCodes.Ldloc, array);
IntConstant.EmitInt (ig, j - idx);
- bool is_stobj;
- OpCode op = ArrayAccess.GetStoreOpcode (t, out is_stobj);
+ bool is_stobj, has_type_arg;
+ OpCode op = ArrayAccess.GetStoreOpcode (t, out is_stobj, out has_type_arg);
if (is_stobj)
ig.Emit (OpCodes.Ldelema, t);
a.Emit (ec);
- if (is_stobj)
- ig.Emit (OpCodes.Stobj, t);
+ if (has_type_arg)
+ ig.Emit (op, t);
else
ig.Emit (op);
}
return;
if (!is_static){
- if (decl_type.IsValueType)
+ if (TypeManager.IsValueType (decl_type))
struct_call = true;
//
// If this is ourselves, push "this"
//
// Push the instance expression
//
- if (instance_expr.Type.IsValueType){
+ if (TypeManager.IsValueType (instance_expr.Type)){
//
// Special case: calls to a function declared in a
// reference-type with a value-type argument need
// to have their value boxed.
- struct_call = true;
- if (decl_type.IsValueType){
+ if (!instance_expr.Type.IsGenericParameter)
+ struct_call = true;
+ if (TypeManager.IsValueType (decl_type)){
//
// If the expression implements IMemoryLocation, then
// we can optimize and use AddressOf on the
ig.Emit (OpCodes.Call,
TypeManager.void_initializearray_array_fieldhandle);
}
-
+
//
// Emits pieces of the array that can not be computed at compile
// time (variables and string locations).
// If we are dealing with a struct, get the
// address of it, so we can store it.
//
- if ((dims == 1) &&
+ if ((dims == 1) &&
etype.IsSubclassOf (TypeManager.value_type) &&
- (!TypeManager.IsBuiltinType (etype) ||
+ (!TypeManager.IsBuiltinOrEnum (etype) ||
etype == TypeManager.decimal_type)) {
if (e is New){
New n = (New) e;
ig.Emit (OpCodes.Ldelema, etype);
}
+ ig.Emit (OpCodes.Nop);
e.Emit (ec);
+ ig.Emit (OpCodes.Nop);
+ ig.Emit (OpCodes.Nop);
if (dims == 1)
ArrayAccess.EmitStoreOpcode (ig, array_element_type);
// a FieldExpr
//
- if (ee.EventInfo.DeclaringType == ec.ContainerType) {
+ if (ee.EventInfo.DeclaringType == ec.ContainerType ||
+ TypeManager.IsNestedChildOf(ec.ContainerType, ee.EventInfo.DeclaringType)) {
MemberInfo mi = GetFieldFromEvent (ee);
if (mi == null) {
return null;
}
- public Expression DoResolve (EmitContext ec, Expression right_side, ResolveFlags flags)
+ public virtual Expression DoResolve (EmitContext ec, Expression right_side,
+ ResolveFlags flags)
{
if (type != null)
throw new Exception ();
else if (type.IsValueType){
ig.Emit (OpCodes.Ldelema, type);
ig.Emit (OpCodes.Ldobj, type);
- } else
+ } else if (type.IsGenericParameter)
+ ig.Emit (OpCodes.Ldelem_Any, type);
+ else
ig.Emit (OpCodes.Ldelem_Ref);
}
/// </summary>
static public void EmitStoreOpcode (ILGenerator ig, Type t)
{
- bool is_stobj;
- OpCode op = GetStoreOpcode (t, out is_stobj);
- if (is_stobj)
- ig.Emit (OpCodes.Stobj, t);
+ bool is_stobj, has_type_arg;
+ OpCode op = GetStoreOpcode (t, out is_stobj, out has_type_arg);
+ if (has_type_arg)
+ ig.Emit (op, t);
else
ig.Emit (op);
}
/// Returns the right opcode to store an object of Type `t'
/// from an array of T.
/// </summary>
- static public OpCode GetStoreOpcode (Type t, out bool is_stobj)
+ static public OpCode GetStoreOpcode (Type t, out bool is_stobj, out bool has_type_arg)
{
//Console.WriteLine (new System.Diagnostics.StackTrace ());
- is_stobj = false;
+ has_type_arg = false; is_stobj = false;
t = TypeManager.TypeToCoreType (t);
if (TypeManager.IsEnumType (t) && t != TypeManager.enum_type)
t = TypeManager.EnumToUnderlying (t);
else if (t == TypeManager.double_type)
return OpCodes.Stelem_R8;
else if (t == TypeManager.intptr_type) {
- is_stobj = true;
+ has_type_arg = true;
+ is_stobj = true;
return OpCodes.Stobj;
} else if (t.IsValueType) {
+ has_type_arg = true;
is_stobj = true;
return OpCodes.Stobj;
+ } else if (t.IsGenericParameter) {
+ has_type_arg = true;
+ return OpCodes.Stelem_Any;
} else
return OpCodes.Stelem_Ref;
}
if (ltype == null)
return null;
+ if (ltype.IsGenericParameter) {
+ int rank = dim.Length-2;
+ if ((rank < 0) || (dim [0] != '[') || (dim [rank+1] != ']'))
+ return null;
+ for (int i = 0; i < rank; i++)
+ if (dim [i+1] != ',')
+ return null;
+
+ type = Array.CreateInstance (ltype, rank).GetType ();
+
+ eclass = ExprClass.Type;
+ return this;
+ }
+
//
// ltype.Fullname is already fully qualified, so we can skip
// a lot of probes, and go directly to TypeManager.LookupType