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); }
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; }
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; } }
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); }