return (ParameterData) ip;
} else {
- Console.WriteLine ("Getting parameters for: " + mb);
ParameterInfo [] pi = mb.GetParameters ();
ReflectionParameters rp = new ReflectionParameters (pi);
method_parameter_cache [mb] = rp;
string array_type = t.FullName + "[]";
LocalBuilder array;
- array = ec.GetTemporaryStorage (Type.GetType (array_type));
+ array = ig.DeclareLocal (Type.GetType (array_type));
IntLiteral.EmitInt (ig, count);
ig.Emit (OpCodes.Newarr, t);
ig.Emit (OpCodes.Stloc, array);
int top = arguments.Count;
for (int j = idx; j < top; j++){
+ a = (Argument) arguments [j];
+
ig.Emit (OpCodes.Ldloc, array);
IntLiteral.EmitInt (ig, j - idx);
a.Emit (ec);
- ig.Emit (OpCodes.Stelem_Ref);
+
+ ArrayAccess.EmitStoreOpcode (ig, t);
}
ig.Emit (OpCodes.Ldloc, array);
}
Type t = instance_expr.Type;
instance_expr.Emit (ec);
- LocalBuilder temp = ec.GetTemporaryStorage (t);
+ LocalBuilder temp = ig.DeclareLocal (t);
ig.Emit (OpCodes.Stloc, temp);
ig.Emit (OpCodes.Ldloca, temp);
}
bool IsBuiltinType = false;
+ int dimensions = 0;
+
public ArrayCreation (string requested_type, ArrayList exprs,
string rank, ArrayList initializers, Location l)
{
public ArrayCreation (string requested_type, string rank, ArrayList initializers, Location l)
{
RequestedType = requested_type;
- Rank = rank;
Initializers = initializers;
loc = l;
+
+ Rank = rank.Substring (0, rank.LastIndexOf ("["));
+
+ string tmp = rank.Substring (rank.LastIndexOf ("["));
+
+ dimensions = tmp.Length - 1;
}
public static string FormArrayType (string base_type, int idx_count, string rank)
return val.Substring (0, val.LastIndexOf ("["));
}
+
+ void error178 ()
+ {
+ Report.Error (178, loc, "Incorrectly structured array initializer");
+ }
+
+ bool ValidateInitializers (EmitContext ec)
+ {
+ if (Initializers == null)
+ return true;
+
+ Type underlying_type = ec.TypeContainer.LookupType (RequestedType, false);
+
+ ArrayList probe = Initializers;
+
+ if (Arguments != null) {
+ for (int i = 0; i < Arguments.Count; i++) {
+ Argument a = (Argument) Arguments [i];
+
+ Expression e = Expression.Reduce (ec, a.Expr);
+
+ if (!(e is Literal)) {
+ Report.Error (150, loc, "A constant value is expected");
+ return false;
+ }
+
+ int value = (int) ((Literal) e).GetValue ();
+ if (probe == null) {
+ error178 ();
+ return false;
+ }
+
+ if (value != probe.Count) {
+ error178 ();
+ return false;
+ }
+
+ if (probe [0] is ArrayList)
+ probe = (ArrayList) probe [0];
+ else {
+ for (int j = 0; j < probe.Count; ++j) {
+ Expression tmp = (Expression) probe [j];
+
+ tmp = tmp.Resolve (ec);
+
+ Expression conv = ConvertImplicitRequired (ec, tmp,
+ underlying_type, loc);
+ if (conv == null)
+ return false;
+ }
+
+ probe = null;
+ }
+ }
+
+ } else {
+ //
+ // Here is where we update dimension info in the case
+ // that the user skips doing that
+ //
+
+ Arguments = new ArrayList ();
+
+ for (probe = Initializers; probe != null; ) {
+ Expression e = new IntLiteral (probe.Count);
+
+ Arguments.Add (new Argument (e, Argument.AType.Expression));
+
+ if (probe [0] is ArrayList)
+ probe = (ArrayList) probe [0];
+ else {
+ for (int j = 0; j < probe.Count; ++j) {
+ Expression tmp = (Expression) probe [j];
+
+ tmp = tmp.Resolve (ec);
+
+ Expression conv = ConvertImplicitRequired (ec, tmp,
+ underlying_type, loc);
+
+ if (conv == null)
+ return false;
+ }
+
+ probe = null;
+ }
+ }
+
+ if (Arguments.Count != dimensions) {
+ error178 ();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public override Expression DoResolve (EmitContext ec)
{
int arg_count;
-
+
+ if (!ValidateInitializers (ec))
+ return null;
+
if (Arguments == null)
arg_count = 0;
else
else
ig.Emit (OpCodes.Ldelem_Ref);
}
+
+ // <summary>
+ // Emits the right opcode to store an object of Type `t'
+ // from an array of T.
+ // </summary>
+ static public void EmitStoreOpcode (ILGenerator ig, Type t)
+ {
+ if (t == TypeManager.byte_type || t == TypeManager.sbyte_type)
+ ig.Emit (OpCodes.Stelem_I1);
+ else if (t == TypeManager.short_type || t == TypeManager.ushort_type)
+ ig.Emit (OpCodes.Stelem_I2);
+ else if (t == TypeManager.int32_type || t == TypeManager.uint32_type)
+ ig.Emit (OpCodes.Stelem_I4);
+ else if (t == TypeManager.int64_type || t == TypeManager.uint64_type)
+ ig.Emit (OpCodes.Stelem_I8);
+ else if (t == TypeManager.float_type)
+ ig.Emit (OpCodes.Stelem_R4);
+ else if (t == TypeManager.double_type)
+ ig.Emit (OpCodes.Stelem_R8);
+ else if (t == TypeManager.intptr_type)
+ ig.Emit (OpCodes.Stelem_I);
+ else
+ ig.Emit (OpCodes.Stelem_Ref);
+ }
public override void Emit (EmitContext ec)
{
source.Emit (ec);
Type t = source.Type;
- if (rank == 1){
- if (t == TypeManager.byte_type || t == TypeManager.sbyte_type)
- ig.Emit (OpCodes.Stelem_I1);
- else if (t == TypeManager.short_type || t == TypeManager.ushort_type)
- ig.Emit (OpCodes.Stelem_I2);
- else if (t == TypeManager.int32_type || t == TypeManager.uint32_type)
- ig.Emit (OpCodes.Stelem_I4);
- else if (t == TypeManager.int64_type || t == TypeManager.uint64_type)
- ig.Emit (OpCodes.Stelem_I8);
- else if (t == TypeManager.float_type)
- ig.Emit (OpCodes.Stelem_R4);
- else if (t == TypeManager.double_type)
- ig.Emit (OpCodes.Stelem_R8);
- else if (t == TypeManager.intptr_type)
- ig.Emit (OpCodes.Stelem_I);
- else
- ig.Emit (OpCodes.Stelem_Ref);
- } else {
+ if (rank == 1)
+ EmitStoreOpcode (ig, t);
+ else {
ModuleBuilder mb = ec.TypeContainer.RootContext.ModuleBuilder;
Type [] args = new Type [ea.Arguments.Count + 1];
MethodInfo set;