internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags) { if (i >= 3 && (flags[i - 0] & InstructionFlags.BranchTarget) == 0 && (flags[i - 1] & InstructionFlags.BranchTarget) == 0 && (flags[i - 2] & InstructionFlags.BranchTarget) == 0 && (flags[i - 3] & InstructionFlags.BranchTarget) == 0 && code[i - 1].NormalizedOpCode == NormalizedByteCode.__ldc_nothrow && code[i - 2].NormalizedOpCode == NormalizedByteCode.__ldc && code[i - 3].NormalizedOpCode == NormalizedByteCode.__ldc) { // we now have a structural match, now we need to make sure that the argument values are what we expect TypeWrapper tclass = classFile.GetConstantPoolClassType(code[i - 3].Arg1); TypeWrapper vclass = classFile.GetConstantPoolClassType(code[i - 2].Arg1); string fieldName = classFile.GetConstantPoolConstantString(code[i - 1].Arg1); if (tclass == wrapper && !vclass.IsUnloadable && !vclass.IsPrimitive && !vclass.IsNonPrimitiveValueType) { FieldWrapper field = wrapper.GetFieldWrapper(fieldName, vclass.SigName); if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass) { // everything matches up, now call the actual emitter ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Newobj, context.GetAtomicReferenceFieldUpdater(field)); return(true); } } } return(false); }
internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags) { if (i >= 3 && (flags[i - 0] & InstructionFlags.BranchTarget) == 0 && (flags[i - 1] & InstructionFlags.BranchTarget) == 0 && (flags[i - 2] & InstructionFlags.BranchTarget) == 0 && (flags[i - 3] & InstructionFlags.BranchTarget) == 0 && code[i - 1].NormalizedOpCode == NormalizedByteCode.__ldc && code[i - 2].NormalizedOpCode == NormalizedByteCode.__ldc && code[i - 3].NormalizedOpCode == NormalizedByteCode.__ldc) { // we now have a structural match, now we need to make sure that the argument values are what we expect TypeWrapper tclass = classFile.GetConstantPoolClassType(code[i - 3].Arg1); TypeWrapper vclass = classFile.GetConstantPoolClassType(code[i - 2].Arg1); string fieldName = classFile.GetConstantPoolConstantString(code[i - 1].Arg1); if (tclass == wrapper && !vclass.IsUnloadable && !vclass.IsPrimitive && !vclass.IsNonPrimitiveValueType) { FieldWrapper field = wrapper.GetFieldWrapper(fieldName, vclass.SigName); if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass) { // everything matches up, now call the actual emitter DoEmit(context, wrapper, ilgen, field); return true; } } } return false; }
internal Field(ClassFile classFile, string[] utf8_cp, BigEndianBinaryReader br) : base(classFile, utf8_cp, br) { if((IsPrivate && IsPublic) || (IsPrivate && IsProtected) || (IsPublic && IsProtected) || (IsFinal && IsVolatile) || (classFile.IsInterface && (!IsPublic || !IsStatic || !IsFinal || IsTransient))) { throw new ClassFormatError("{0} (Illegal field modifiers: 0x{1:X})", classFile.Name, access_flags); } int attributes_count = br.ReadUInt16(); for(int i = 0; i < attributes_count; i++) { switch(classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16())) { case "Deprecated": if(br.ReadUInt32() != 0) { throw new ClassFormatError("Invalid Deprecated attribute length"); } flags |= FLAG_MASK_DEPRECATED; break; case "ConstantValue": { if(br.ReadUInt32() != 2) { throw new ClassFormatError("Invalid ConstantValue attribute length"); } ushort index = br.ReadUInt16(); try { switch(Signature) { case "I": constantValue = classFile.GetConstantPoolConstantInteger(index); break; case "S": constantValue = (short)classFile.GetConstantPoolConstantInteger(index); break; case "B": constantValue = (byte)classFile.GetConstantPoolConstantInteger(index); break; case "C": constantValue = (char)classFile.GetConstantPoolConstantInteger(index); break; case "Z": constantValue = classFile.GetConstantPoolConstantInteger(index) != 0; break; case "J": constantValue = classFile.GetConstantPoolConstantLong(index); break; case "F": constantValue = classFile.GetConstantPoolConstantFloat(index); break; case "D": constantValue = classFile.GetConstantPoolConstantDouble(index); break; case "Ljava.lang.String;": constantValue = classFile.GetConstantPoolConstantString(index); break; default: throw new ClassFormatError("{0} (Invalid signature for constant)", classFile.Name); } } catch(InvalidCastException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } catch(IndexOutOfRangeException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } catch(InvalidOperationException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } catch(NullReferenceException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } break; } case "Signature": if(classFile.MajorVersion < 49) { goto default; } if(br.ReadUInt32() != 2) { throw new ClassFormatError("Signature attribute has incorrect length"); } signature = classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16()); break; case "RuntimeVisibleAnnotations": if(classFile.MajorVersion < 49) { goto default; } annotations = ReadAnnotations(br, classFile, utf8_cp); break; case "RuntimeInvisibleAnnotations": if(classFile.MajorVersion < 49) { goto default; } foreach(object[] annot in ReadAnnotations(br, classFile, utf8_cp)) { if(annot[1].Equals("Likvm/lang/Property;")) { DecodePropertyAnnotation(classFile, annot); } #if STATIC_COMPILER else if(annot[1].Equals("Likvm/lang/Internal;")) { this.access_flags &= ~Modifiers.AccessMask; flags |= FLAG_MASK_INTERNAL; } #endif } break; default: br.Skip(br.ReadUInt32()); break; } } }
internal string GetStringLiteral(int offset) { return(ClassFile.GetConstantPoolConstantString(Code[OpcodeIndex + offset].Arg1)); }
internal Field(ClassFile classFile, BigEndianBinaryReader br) : base(classFile, br) { if ((IsPrivate && IsPublic) || (IsPrivate && IsProtected) || (IsPublic && IsProtected) || (IsFinal && IsVolatile) || (classFile.IsInterface && (!IsPublic || !IsStatic || !IsFinal || IsTransient))) { throw new ClassFormatError("{0} (Illegal field modifiers: 0x{1:X})", classFile.Name, access_flags); } int attributes_count = br.ReadUInt16(); for (int i = 0; i < attributes_count; i++) { switch (classFile.GetConstantPoolUtf8String(br.ReadUInt16())) { case "Deprecated": deprecated = true; #if FUZZ_HACK br.Skip(br.ReadUInt32()); #else if(br.ReadUInt32() != 0) { throw new ClassFormatError("Deprecated attribute has non-zero length"); } #endif break; case "ConstantValue": { if (br.ReadUInt32() != 2) { throw new ClassFormatError("Invalid ConstantValue attribute length"); } ushort index = br.ReadUInt16(); try { switch (Signature) { case "I": constantValue = classFile.GetConstantPoolConstantInteger(index); break; case "S": constantValue = (short) classFile.GetConstantPoolConstantInteger(index); break; case "B": constantValue = (byte) classFile.GetConstantPoolConstantInteger(index); break; case "C": constantValue = (char) classFile.GetConstantPoolConstantInteger(index); break; case "Z": constantValue = classFile.GetConstantPoolConstantInteger(index) != 0; break; case "J": constantValue = classFile.GetConstantPoolConstantLong(index); break; case "F": constantValue = classFile.GetConstantPoolConstantFloat(index); break; case "D": constantValue = classFile.GetConstantPoolConstantDouble(index); break; case "Ljava.lang.String;": constantValue = classFile.GetConstantPoolConstantString(index); break; default: throw new ClassFormatError("{0} (Invalid signature for constant)", classFile.Name); } } catch (InvalidCastException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } catch (IndexOutOfRangeException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } catch (InvalidOperationException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } catch (NullReferenceException) { throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name); } break; } default: br.Skip(br.ReadUInt32()); break; } } }