Ejemplo n.º 1
0
        /// <exception cref="System.IO.IOException"/>
        public StructClass(DataInputFullStream @in, bool own, LazyLoader loader)
        {
            /*
             * class_file {
             * u4 magic;
             * u2 minor_version;
             * u2 major_version;
             * u2 constant_pool_count;
             * cp_info constant_pool[constant_pool_count-1];
             * u2 access_flags;
             * u2 this_class;
             * u2 super_class;
             * u2 interfaces_count;
             * u2 interfaces[interfaces_count];
             * u2 fields_count;
             * field_info fields[fields_count];
             * u2 methods_count;
             * method_info methods[methods_count];
             * u2 attributes_count;
             * attribute_info attributes[attributes_count];
             * }
             */
            this.own    = own;
            this.loader = loader;
            @in.Discard(4);
            minorVersion = @in.ReadUnsignedShort();
            majorVersion = @in.ReadUnsignedShort();
            pool         = new ConstantPool(@in);
            accessFlags  = @in.ReadUnsignedShort();
            int thisClassIdx  = @in.ReadUnsignedShort();
            int superClassIdx = @in.ReadUnsignedShort();

            qualifiedName = pool.GetPrimitiveConstant(thisClassIdx).GetString();
            superClass    = pool.GetPrimitiveConstant(superClassIdx);
            // interfaces
            int length = @in.ReadUnsignedShort();

            interfaces     = new int[length];
            interfaceNames = new string[length];
            for (int i = 0; i < length; i++)
            {
                interfaces[i]     = @in.ReadUnsignedShort();
                interfaceNames[i] = pool.GetPrimitiveConstant(interfaces[i]).GetString();
            }
            // fields
            length = @in.ReadUnsignedShort();
            fields = new VBStyleCollection <StructField, string>(length);
            for (int i = 0; i < length; i++)
            {
                StructField field = new StructField(@in, this);
                fields.AddWithKey(field, InterpreterUtil.MakeUniqueKey(field.GetName(), field.GetDescriptor
                                                                           ()));
            }
            // methods
            length  = @in.ReadUnsignedShort();
            methods = new VBStyleCollection <StructMethod, string>(length);
            for (int i = 0; i < length; i++)
            {
                StructMethod method = new StructMethod(@in, this);
                methods.AddWithKey(method, InterpreterUtil.MakeUniqueKey(method.GetName(), method
                                                                         .GetDescriptor()));
            }
            // attributes
            attributes = ReadAttributes(@in, pool);
            ReleaseResources();
        }
        /// <exception cref="IOException"/>
        public static Exprent ParseAnnotationElement(DataInputStream data, ConstantPool pool
                                                     )
        {
            int tag = data.ReadUnsignedByte();

            switch (tag)
            {
            case 'e':
            {
                // enum constant
                string className = pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString(
                    );
                string constName = pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString(
                    );
                FieldDescriptor descr = FieldDescriptor.ParseDescriptor(className);
                return(new FieldExprent(constName, descr.type.value, true, null, descr, null));
            }

            case 'c':
            {
                // class
                string descriptor = pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString
                                        ();
                VarType type = FieldDescriptor.ParseDescriptor(descriptor).type;
                string  value;
                switch (type.type)
                {
                case ICodeConstants.Type_Object:
                {
                    value = type.value;
                    break;
                }

                case ICodeConstants.Type_Byte:
                {
                    value = typeof(byte).FullName;
                    break;
                }

                case ICodeConstants.Type_Char:
                {
                    value = typeof(char).FullName;
                    break;
                }

                case ICodeConstants.Type_Double:
                {
                    value = typeof(double).FullName;
                    break;
                }

                case ICodeConstants.Type_Float:
                {
                    value = typeof(float).FullName;
                    break;
                }

                case ICodeConstants.Type_Int:
                {
                    value = typeof(int).FullName;
                    break;
                }

                case ICodeConstants.Type_Long:
                {
                    value = typeof(long).FullName;
                    break;
                }

                case ICodeConstants.Type_Short:
                {
                    value = typeof(short).FullName;
                    break;
                }

                case ICodeConstants.Type_Boolean:
                {
                    value = typeof(bool).FullName;
                    break;
                }

                case ICodeConstants.Type_Void:
                {
                    value = typeof(void).FullName;
                    break;
                }

                default:
                {
                    throw new Exception("invalid class type: " + type.type);
                }
                }
                return(new ConstExprent(VarType.Vartype_Class, value, null));
            }

            case '[':
            {
                // array
                List <Exprent> elements = new System.Collections.Generic.List <Exprent>();
                int            len      = data.ReadUnsignedShort();
                if (len > 0)
                {
                    elements = new List <Exprent>(len);
                    for (int i = 0; i < len; i++)
                    {
                        elements.Add(ParseAnnotationElement(data, pool));
                    }
                }
                VarType newType;
                if ((elements.Count == 0))
                {
                    newType = new VarType(ICodeConstants.Type_Object, 1, "java/lang/Object");
                }
                else
                {
                    VarType elementType = elements[0].GetExprType();
                    newType = new VarType(elementType.type, 1, elementType.value);
                }
                NewExprent newExpr = new NewExprent(newType, new System.Collections.Generic.List <
                                                        Exprent>(), null);
                newExpr.SetDirectArrayInit(true);
                newExpr.SetLstArrayElements(elements);
                return(newExpr);
            }

            case '@':
            {
                // annotation
                return(ParseAnnotation(data, pool));
            }

            default:
            {
                PrimitiveConstant cn = pool.GetPrimitiveConstant(data.ReadUnsignedShort());
                switch (tag)
                {
                case 'B':
                {
                    return(new ConstExprent(VarType.Vartype_Byte, cn.value, null));
                }

                case 'C':
                {
                    return(new ConstExprent(VarType.Vartype_Char, cn.value, null));
                }

                case 'D':
                {
                    return(new ConstExprent(VarType.Vartype_Double, cn.value, null));
                }

                case 'F':
                {
                    return(new ConstExprent(VarType.Vartype_Float, cn.value, null));
                }

                case 'I':
                {
                    return(new ConstExprent(VarType.Vartype_Int, cn.value, null));
                }

                case 'J':
                {
                    return(new ConstExprent(VarType.Vartype_Long, cn.value, null));
                }

                case 'S':
                {
                    return(new ConstExprent(VarType.Vartype_Short, cn.value, null));
                }

                case 'Z':
                {
                    return(new ConstExprent(VarType.Vartype_Boolean, cn.value, null));
                }

                case 's':
                {
                    return(new ConstExprent(VarType.Vartype_String, cn.value, null));
                }

                default:
                {
                    throw new Exception("invalid element type!");
                }
                }
                break;
            }
            }
        }