package remotesoft.cormd; import remotesoft.cormd.MemberRef; import remotesoft.javac.v8.util.*; import remotesoft.msil.*; import remotesoft.salamander.CSharpKeywords; import remotesoft.salamander.CSharpWriter; import remotesoft.salamander.ClassWriter; import remotesoft.salamander.ILAsmWriter; /** Decompile a custom attribute */ public class CustomAttribute { /** The raw methodref token */ protected int methodRefToken; /** The constructor to form this attribute */ protected MemberRef constructor; /* constant values for constructor args */ protected Object[] args; protected NamedArg[] namedArgs; /** Attribute could attach to type, method, field, property, event, delegate, method parameter, etc., target specifies to which object it attaches. */ protected Object target; /** in which type this attribute's target is defined */ TypeInfo classfile = null; public CustomAttribute(int mdMethodRef, Object[] args, NamedArg[] namedArgs, Object target) { methodRefToken = mdMethodRef; this.args = args; this.namedArgs = namedArgs; this.target = target; classfile = getTypeInfo(target); constructor = classfile.getMethodRef(methodRefToken); } // also called from C++ private static TypeInfo getTypeInfo(Object target) { TypeInfo typedef = null; if (target instanceof TypeInfo) { typedef = (TypeInfo)target; } else if (target instanceof MemberInfo) { typedef = ((MemberInfo)target).getDeclaringType(); } else if (target instanceof ParameterInfo) { typedef = ((ParameterInfo)target).parent.getDeclaringType(); } else if (target instanceof ModuleInfo) { typedef = ((ModuleInfo)target).getGlobalType(); } else { System.err.println("CustomAttribute target yet to handle: " + target.getClass().getName()); } return typedef; } public Object[] getArgs() { return args; } public NamedArg[] getNamedArgs() { return namedArgs; } private static void emitStringAsILAsm(ByteBuffer buf, String str) { if (str == null) { buf.appendByte(-1); return; } int len = str.length(); if (len <= 127) { buf.appendByte((byte)len); } else if (len <= 16383) { buf.appendByte((byte)(len >> 8 | 128)); buf.appendByte((byte)(len & 255)); } else { buf.appendByte((byte)(len >> 24 | 192)); buf.appendByte((byte)(len >> 16 & 255)); buf.appendByte((byte)(len >> 8 & 255)); buf.appendByte((byte)(len & 255)); } Name nm = Name.fromString(str); byte[] utfs = nm.toUtf(); buf.appendBytes(utfs); } /** write a constant value according to ILAsm custom attribute blob format */ private void writeValueAsILAsm(ByteBuffer tmp, Type t, Object val) { if (t.isBoolean()) { boolean z = ((Boolean)val).booleanValue(); tmp.appendByte(z?1:0); } else if (t.isI1()) { byte b = ((Byte)val).byteValue(); tmp.appendByte(b); } else if (t.isU1()) { short s = ((Short)val).shortValue(); tmp.appendByte((byte)s); } else if (t.isChar()) { char c = ((Character)val).charValue(); tmp.appendCharWithLittleEndian(c); } else if (t.isU2()) { int n = ((Integer)val).intValue(); tmp.appendShortWithLittleEndian((short)n); } else if (t.isI2()) { short s = ((Short)val).shortValue(); tmp.appendShortWithLittleEndian(s); } else if (t.isI4()) { int n = ((Integer)val).intValue(); tmp.appendIntWithLittleEndian(n); } else if (t.isU4()) { long l = ((Long)val).longValue(); tmp.appendIntWithLittleEndian((int)l); } else if (t.isI8() || t.isU8()) { long l = ((Long)val).longValue(); tmp.appendLongWithLittleEndian(l); } else if (t.isR4()) { float f = ((Float)val).floatValue(); tmp.appendFloatWithLittleEndian(f); } else if (t.isR8()) { double d = ((Double)val).doubleValue(); tmp.appendDoubleWithLittleEndian(d); } else if (t.isString() || t.equals(Type.System_Type)) { emitStringAsILAsm(tmp, (String)val); } else if (t.isSZArray()) { Object[] values = (Object[])val; if (values == null) { tmp.appendByte(-1); } else {// a int32 length followed by that number of elem values tmp.appendIntWithLittleEndian(values.length); for (int i=0; i 0) { fullyQualifiedName = fullyQualifiedName.substring(0, comma); } buf.appendString(classfile.toSimpleName(fullyQualifiedName)); buf.appendByte(')'); } else if (t.isSZArray()) { if (!remotesoft.salamander.Main.writer.isCPP()) { buf.appendName(CSharpKeywords._new); buf.appendByte(' '); buf.appendString(t.toString()); } buf.appendByte('{'); Object[] values = (Object[])val; for (int j=0; j [SerializableAttribute], OK if (remotesoft.salamander.Main.writer.isCPP() && constructor.getSignature().getArgTypes().length ==0 && namedArgs.length == 0) { buf.appendByte(']'); return; } buf.appendByte('('); // here comes the arguments Type[] argTypes = constructor.getSignature().getArgTypes(); for (int i=0; i