예제 #1
0
        private static Item CompileNewArray(ByteCodeGenerator generator, NewNode.NewArrayNode node)
        {
            var elemType = node.GetType(generator);
            var type = node.GetType(generator);

            foreach (var expression in node.Dimensions)
            {
                new ExpressionCompiler(expression).Compile(generator).Coerce(PrimativeTypes.Int).Load();

                type = new Array(type);
            }

            var ndims = (byte)node.Dimensions.Count;

            var elemcode = TypeCodeHelper.ArrayCode((type as Array).ArrayType);
            if (elemcode == 0 || (elemcode == 1 && ndims == 1))
            {
                generator.EmitAnewarray(generator.Manager.AddConstantClass(elemType), type);
            }
            else if (elemcode == 1)
            {
                generator.EmitMultianewarray(ndims, generator.Manager.AddConstantClass(type), type);
            }
            else
            {
                generator.EmitNewarray(elemcode, type);
            }

            return new StackItem(generator, type);
        }
예제 #2
0
        public Type Walk()
        {
            var typeRef = ProcessClass(node.GetChild(0));

            if (node.ChildCount > 1)
            {
                var arrayLevels = ProcessArray(node.GetChild(1));

                for (var i = 0; i < arrayLevels; i++)
                {
                    typeRef = new Array(typeRef);
                }
            }

            return typeRef;
        }
예제 #3
0
        private static Type GetTypeFromDescriptor(string descriptor)
        {
            if (descriptor.Length == 1)
            {
                switch (descriptor)
                {
                    case "B":
                        return PrimativeTypes.Byte;
                    case "C":
                        return PrimativeTypes.Char;
                    case "D":
                        return PrimativeTypes.Double;
                    case "F":
                        return PrimativeTypes.Float;
                    case "I":
                        return PrimativeTypes.Int;
                    case "J":
                        return PrimativeTypes.Long;
                    case "S":
                        return PrimativeTypes.Short;
                    case "Z":
                        return PrimativeTypes.Boolean;
                    case "V":
                        return PrimativeTypes.Void;
                    default:
                        throw new NotImplementedException();
                }
            }

            int arrayDimensions = descriptor.TakeWhile(x => x == '[').Count();
            descriptor = new string(descriptor.SkipWhile(x => x == '[').ToArray());

            if (descriptor.Length == 1)
            {
                Type type = GetTypeFromDescriptor(descriptor);

                for (var i = 0; i < arrayDimensions; i++)
                {
                    type = new Array(type);
                }

                return type;
            }

            if (descriptor[0] != 'L') throw new ArgumentException();
            if (descriptor[descriptor.Length - 1] != ';') throw new ArgumentException();

            {
                Type type = new PlaceholderType
                               {
                                   Name = descriptor.Replace('/', '.').Substring(1, descriptor.Length - 2)
                               };

                for (var i = 0; i < arrayDimensions; i++)
                {
                    type = new Array(type);
                }

                return type;
            }
        }
예제 #4
0
        private static Tuple<List<Type>, Type> GetMethodTypeFromDescriptor(string descriptor)
        {
            int i = 0;
            if (descriptor[i++] != '(') throw new ArgumentException();

            var parameterTypes = new List<Type>();

            while (descriptor[i] != ')')
            {
                switch (descriptor[i++])
                {
                    case 'B':
                    case 'C':
                    case 'D':
                    case 'F':
                    case 'I':
                    case 'J':
                    case 'S':
                    case 'Z':
                        parameterTypes.Add(GetTypeFromDescriptor(new string(new[] { descriptor[i - 1] })));
                        break;
                    case 'L':
                        {
                            string typeName = "";
                            while (descriptor[i] != ';')
                            {
                                typeName += descriptor[i++];
                            }
                            i++;

                            parameterTypes.Add(new PlaceholderType { Name = typeName.Replace('/', '.') });
                        }
                        break;
                    case '[':
                        {
                            int arrayDimensions = 1;
                            while (descriptor[i] == '[')
                            {
                                arrayDimensions++;
                                i++;
                            }

                            Type type;
                            if (descriptor[i] == 'L')
                            {
                                var typeName = "";

                                i++;

                                while (descriptor[i] != ';')
                                {
                                    typeName += descriptor[i++];
                                }

                                type = new PlaceholderType { Name = typeName.Replace('/', '.') };
                            }
                            else
                            {
                                type = GetTypeFromDescriptor(new string(new[] { descriptor[i] }));
                            }
                            i++;

                            for (var x = 0; x < arrayDimensions; x++)
                            {
                                type = new Array(type);
                            }

                            parameterTypes.Add(type);
                        }
                        break;
                    default:
                        throw new NotImplementedException();
                }
            }

            if (descriptor[i++] != ')') throw new ArgumentException();

            Type returnType = GetTypeFromDescriptor(descriptor.Substring(i));

            return new Tuple<List<Type>, Type>(parameterTypes, returnType);
        }