Пример #1
0
        public static bool LoadStore(bool isLoad, CilType stackTop, JavaType opcodeType,
                                     CilType dataType, JavaCode code)
        {
            if (stackTop.Equals(SpanType) && code.Method.Class.Name != SpanType.ClassName)
            {
                string opcodeDescr;
                if (opcodeType == null)
                {
                    opcodeType  = CilType.SystemValueType;
                    opcodeDescr = "";

                    // at this point we should have been called from LoadObject or
                    // StoreObject in CodeMisc to handle a ldobj/stobj instruction,
                    // so make sure the pointer-span element is a value type
                    if (dataType.IsGenericParameter || (!dataType.IsValueClass))
                    {
                        throw new InvalidProgramException();
                    }
                    code.NewInstruction(0x12 /* ldc */, dataType.AsWritableClass, null);

                    // make sure the stack has room for three parameters:
                    // 'this', value reference (in case of Store), and class
                    code.StackMap.PushStack(JavaType.ObjectType);
                    code.StackMap.PushStack(JavaType.ObjectType);
                    code.StackMap.PushStack(JavaType.ObjectType);
                    code.StackMap.PopStack(CilMain.Where);
                    code.StackMap.PopStack(CilMain.Where);
                    code.StackMap.PopStack(CilMain.Where);
                }
                else
                {
                    if (opcodeType.Equals(JavaType.ShortType) &&
                        stackTop.GenericParameters != null &&
                        stackTop.GenericParameters[0].Equals(JavaType.CharacterType))
                    {
                        opcodeType = JavaType.CharacterType;
                    }

                    opcodeDescr = opcodeType.ToDescriptor();
                }

                var voidType   = JavaType.VoidType;
                var spanMethod = isLoad
                      ? (new JavaMethodRef("Load" + opcodeDescr, opcodeType))
                      : (new JavaMethodRef("Store" + opcodeDescr, voidType, opcodeType));
                if (opcodeDescr == "")
                {
                    spanMethod.Parameters.Add(new JavaFieldRef("", JavaType.ClassType));
                }
                code.NewInstruction(0xB6 /* invokevirtual */, SpanType, spanMethod);
                if (isLoad)
                {
                    code.StackMap.PushStack(CilType.From(opcodeType));
                }

                return(true);
            }
            return(false);
        }