void CallInstructionTranslator() { switch (cilOp) { case Code.Nop: case Code.Volatile: case Code.Constrained: case Code.Unaligned: case Code.Readonly: case Code.Tail: code.NewInstruction(0x00 /* nop */, null, null); break; case Code.Break: code.NewInstruction(0xCA /* debugger break */, null, null); break; case Code.Pop: case Code.Dup: PopOrDupStack(cilOp); break; case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldarg: case Code.Ldarg_S: case Code.Ldloc: case Code.Ldloc_S: locals.LoadValue(cilOp, cilInst.Operand); break; case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: case Code.Starg: case Code.Starg_S: case Code.Stloc: case Code.Stloc_S: locals.StoreValue(cilOp, cilInst.Operand); break; case Code.Ldarga: case Code.Ldloca: case Code.Ldarga_S: case Code.Ldloca_S: locals.LoadAddress(cilInst.Operand); break; case Code.Ldc_I4_M1: case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: case Code.Ldc_I4_S: case Code.Ldc_I4: case Code.Ldc_I8: case Code.Ldc_R4: case Code.Ldc_R8: case Code.Ldstr: case Code.Ldnull: LoadConstant(cilOp, cilInst); break; case Code.Ldfld: case Code.Ldflda: case Code.Stfld: case Code.Ldsfld: case Code.Ldsflda: case Code.Stsfld: LoadStoreField(cilOp, cilInst.Operand); break; case Code.Initobj: InitObject(cilInst.Operand); break; case Code.Newobj: case Code.Call: case Code.Callvirt: case Code.Ret: CallMethod(cilOp, cilInst.Operand); break; case Code.Castclass: CastToClass(cilInst.Operand); break; case Code.Ldtoken: LoadToken(); break; case Code.Unbox: case Code.Unbox_Any: UnboxObject(cilOp, cilInst.Operand); break; case Code.Ldobj: case Code.Box: LoadObject(cilOp, cilInst.Operand); break; case Code.Stobj: StoreObject(cilInst.Operand); break; case Code.Br: case Code.Br_S: case Code.Brtrue: case Code.Brtrue_S: case Code.Beq: case Code.Beq_S: case Code.Bgt: case Code.Bgt_S: case Code.Bgt_Un: case Code.Bgt_Un_S: case Code.Blt: case Code.Blt_S: case Code.Blt_Un: case Code.Blt_Un_S: CodeCompare.Straight(code, cilOp, locals, cilInst); break; case Code.Brfalse: case Code.Brfalse_S: case Code.Bne_Un: case Code.Bne_Un_S: case Code.Ble: case Code.Ble_S: case Code.Ble_Un: case Code.Ble_Un_S: case Code.Bge: case Code.Bge_S: case Code.Bge_Un: case Code.Bge_Un_S: CodeCompare.Opposite(code, cilOp, locals, cilInst); break; case Code.Cgt: case Code.Cgt_Un: case Code.Ceq: case Code.Clt: case Code.Clt_Un: CodeCompare.Compare(code, cilOp, cilInst); break; case Code.Switch: CodeCompare.Switch(code, cilInst); break; case Code.Isinst: CodeCompare.Instance(code, locals, cilInst); break; case Code.Conv_I1: case Code.Conv_Ovf_I1: case Code.Conv_Ovf_I1_Un: case Code.Conv_I2: case Code.Conv_Ovf_I2: case Code.Conv_Ovf_U2_Un: case Code.Conv_I4: case Code.Conv_Ovf_I4: case Code.Conv_Ovf_I4_Un: case Code.Conv_I8: case Code.Conv_Ovf_I8: case Code.Conv_Ovf_I8_Un: case Code.Conv_U1: case Code.Conv_Ovf_U1: case Code.Conv_Ovf_U1_Un: case Code.Conv_U2: case Code.Conv_Ovf_U2: case Code.Conv_Ovf_I2_Un: case Code.Conv_U4: case Code.Conv_Ovf_U4: case Code.Conv_Ovf_U4_Un: case Code.Conv_U8: case Code.Conv_Ovf_U8: case Code.Conv_Ovf_U8_Un: case Code.Conv_I: case Code.Conv_Ovf_I: case Code.Conv_Ovf_I_Un: case Code.Conv_U: case Code.Conv_Ovf_U: case Code.Conv_Ovf_U_Un: case Code.Conv_R4: case Code.Conv_R8: case Code.Conv_R_Un: CodeNumber.Conversion(code, cilOp, cilInst); break; case Code.Add: case Code.Sub: case Code.Mul: case Code.Neg: case Code.Div: case Code.Div_Un: case Code.Rem: case Code.Rem_Un: case Code.And: case Code.Or: case Code.Xor: case Code.Not: case Code.Shl: case Code.Shr: case Code.Shr_Un: case Code.Add_Ovf: case Code.Add_Ovf_Un: case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Mul_Ovf: case Code.Mul_Ovf_Un: CodeNumber.Calculation(code, cilOp, cilInst); break; case Code.Ldind_I1: case Code.Ldind_U1: case Code.Ldind_I2: case Code.Ldind_U2: case Code.Ldind_I4: case Code.Ldind_U4: case Code.Ldind_I8: case Code.Ldind_I: case Code.Ldind_R4: case Code.Ldind_R8: case Code.Ldind_Ref: case Code.Stind_I1: case Code.Stind_I2: case Code.Stind_I4: case Code.Stind_I8: case Code.Stind_I: case Code.Stind_R4: case Code.Stind_R8: case Code.Stind_Ref: CodeNumber.Indirection(code, cilOp); break; case Code.Throw: case Code.Rethrow: case Code.Leave: case Code.Leave_S: case Code.Endfinally: case Code.Endfilter: exceptions.Translate(cilInst); break; case Code.Newarr: arrays.New(cilInst.Operand); break; case Code.Ldlen: arrays.Length(); break; case Code.Ldelema: arrays.Address(null, cilInst); break; case Code.Ldelem_I1: case Code.Ldelem_U1: case Code.Ldelem_I2: case Code.Ldelem_U2: case Code.Ldelem_I4: case Code.Ldelem_U4: case Code.Ldelem_I8: case Code.Ldelem_I: case Code.Ldelem_R4: case Code.Ldelem_R8: case Code.Ldelem_Ref: case Code.Ldelem_Any: arrays.Load(cilOp, cilInst.Operand, cilInst); break; case Code.Stelem_I1: case Code.Stelem_I2: case Code.Stelem_I4: case Code.Stelem_I8: case Code.Stelem_I: case Code.Stelem_R4: case Code.Stelem_R8: case Code.Stelem_Any: case Code.Stelem_Ref: arrays.Store(cilOp, cilInst); break; case Code.Ldftn: case Code.Ldvirtftn: Delegate.LoadFunction(code, cilInst); break; case Code.Sizeof: CodeSpan.Sizeof(cilInst.Operand, code); break; case Code.Localloc: CodeSpan.Localloc(code); break; /* instructions not handled: * Jmp, Calli, Cpobj, Refanyval, Ckfinite, Mkrefany, Arglist, * Tail, Cpblk, Initblk, No, Refanytype, */ default: throw new InvalidProgramException(); } }
public void New(CilType elemType, int numDims, bool arrayTypeOnStack = false) { var elemTypeForArray = elemType.IsGenericParameter ? CilType.From(JavaType.ObjectType) : elemType; var arrayType = elemTypeForArray.AdjustRank(numDims); if (elemType.IsGenericParameter) { /*if (numDims != 1) * throw new Exception("unsupported number of dimensions in generic array");*/ if (!arrayTypeOnStack) { GenericUtil.LoadMaybeGeneric(elemType, code); } var parameters = new List <JavaFieldRef>(); for (int i = 0; i < numDims; i++) { parameters.Add(new JavaFieldRef("", JavaType.IntegerType)); } parameters.Add(new JavaFieldRef("", CilType.SystemTypeType)); code.NewInstruction(0xB8 /* invokestatic */, SystemArrayType, new JavaMethodRef("New", JavaType.ObjectType, parameters)); stackMap.PopStack(CilMain.Where); // type while (numDims-- > 0) { stackMap.PopStack(CilMain.Where); } arrayType = GenericArrayType; } else if (elemType.IsReference || numDims > 1) { if (numDims == 1) { code.NewInstruction(0xBD /* anewarray */, elemType, null); } else { code.NewInstruction(0xC5 /* multianewarray */, arrayType, numDims); } for (int i = 0; i < numDims; i++) { stackMap.PopStack(CilMain.Where); } stackMap.PushStack(arrayType); // arrayObj if (elemType.ArrayRank != 0) { if (numDims == 1) { // notify the array support methods in baselib that this // is a jagged array, i.e. a single dimension array with // an element type that is also an array. for arrays of // generic type, see system.Array.New() in baselib. stackMap.PushStack(JavaType.ObjectType); code.NewInstruction(0x59 /* dup */, null, null); code.NewInstruction(0xB8 /* invokestatic */, SystemArrayType, new JavaMethodRef("MarkJagged", JavaType.VoidType, JavaType.ObjectType)); stackMap.PopStack(CilMain.Where); } } else if (elemType.IsValueClass) { code.NewInstruction(0x59 /* dup */, null, null); stackMap.PushStack(arrayType); // arrayCopy if (elemType.HasGenericParameters) { // array of a value class ArrayElement<T>, pass this type // as the second parameter to system.Array.Initialize GenericUtil.LoadMaybeGeneric(elemType, code); // third parameter is null code.NewInstruction(0x01 /* aconst_null */, null, null); stackMap.PushStack(JavaType.ObjectType); } else { // array of a plain value class, pass a constructed object // as the third parameter to system.Array.Initialize // second parameter is null code.NewInstruction(0x01 /* aconst_null */, null, null); stackMap.PushStack(CilType.SystemTypeType); // model parameter is a new object code.NewInstruction(0xBB /* new */, elemType.AsWritableClass, null); stackMap.PushStack(elemType); code.NewInstruction(0x59 /* dup */, null, null); stackMap.PushStack(elemType); code.NewInstruction(0xB7 /* invokespecial */, elemType.AsWritableClass, new CilMethod(elemType)); stackMap.PopStack(CilMain.Where); } code.NewInstruction(0x12 /* ldc */, null, numDims); stackMap.PushStack(JavaType.IntegerType); code.NewInstruction(0xB8 /* invokestatic */, SystemArrayType, InitArrayMethod); stackMap.PopStack(CilMain.Where); // numDims stackMap.PopStack(CilMain.Where); // elemType stackMap.PopStack(CilMain.Where); // arrayType stackMap.PopStack(CilMain.Where); // arrayCopy } stackMap.PopStack(CilMain.Where); // arrayObj } else { if (numDims == 1) { var length = stackMap.PopStack(CilMain.Where); stackMap.PushStack(length); if (length.Equals(JavaType.LongType)) { CodeNumber.Conversion(code, Code.Conv_Ovf_I4, null); } } code.NewInstruction(0xBC /* newarray */, null, elemType.NewArrayType); while (numDims-- > 0) { stackMap.PopStack(CilMain.Where); } } stackMap.PushStack(arrayType); }