IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
RuntimeConstantJavaField.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2014 Jeroen Frijters
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25using System.Diagnostics;
26
27using IKVM.Attributes;
28
29#if IMPORTER || EXPORTER
30using IKVM.Reflection;
32
33using Type = IKVM.Reflection.Type;
34#else
35using System.Reflection;
36using System.Reflection.Emit;
37#endif
38
39namespace IKVM.Runtime
40{
41
46 {
47
48 // NOTE this field wrapper can represent a .NET enum, but in that case "constant" contains the raw constant value (i.e. the boxed underlying primitive value, not a boxed enum)
49
53 object constant;
54
67 internal RuntimeConstantJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, object constant, MemberFlags flags) :
68 base(declaringType, fieldType, name, sig, modifiers, field, flags)
69 {
70 if (IsStatic == false)
71 throw new InternalException();
72
73 Debug.Assert(constant == null || constant.GetType().IsPrimitive || constant is string);
74 this.constant = constant;
75 }
76
77 internal object GetConstantValue()
78 {
79 if (constant == null)
80 {
81 var field = GetField();
82 constant = field.GetRawConstantValue();
83 }
84
85 return constant;
86 }
87
88#if EMITTERS
89
90 protected override void EmitGetImpl(CodeEmitter ilgen)
91 {
92 // Reading a field should trigger the cctor, but since we're inlining the value
93 // we have to trigger it explicitly
94 DeclaringType.EmitRunClassConstructor(ilgen);
95
96 // NOTE even though you're not supposed to access a constant static final (the compiler is supposed
97 // to inline them), we have to support it (because it does happen, e.g. if the field becomes final
98 // after the referencing class was compiled, or when we're accessing an unsigned primitive .NET field)
99 var v = GetConstantValue();
100 if (v == null)
101 {
102 ilgen.Emit(OpCodes.Ldnull);
103 }
104 else if (constant is int || constant is short || constant is ushort || constant is byte || constant is sbyte || constant is char || constant is bool)
105 {
106 ilgen.EmitLdc_I4(((IConvertible)constant).ToInt32(null));
107 }
108 else if (constant is string)
109 {
110 ilgen.Emit(OpCodes.Ldstr, (string)constant);
111 }
112 else if (constant is float)
113 {
114 ilgen.EmitLdc_R4((float)constant);
115 }
116 else if (constant is double)
117 {
118 ilgen.EmitLdc_R8((double)constant);
119 }
120 else if (constant is long)
121 {
122 ilgen.EmitLdc_I8((long)constant);
123 }
124 else if (constant is uint)
125 {
126 ilgen.EmitLdc_I4(unchecked((int)((IConvertible)constant).ToUInt32(null)));
127 }
128 else if (constant is ulong)
129 {
130 ilgen.EmitLdc_I8(unchecked((long)(ulong)constant));
131 }
132 else
133 {
134 throw new InvalidOperationException(constant.GetType().FullName);
135 }
136 }
137
138 protected override void EmitSetImpl(CodeEmitter ilgen)
139 {
140 // when constant static final fields are updated, the JIT normally doesn't see that (because the
141 // constant value is inlined), so we emulate that behavior by emitting a Pop
142 ilgen.Emit(OpCodes.Pop);
143 }
144
145#endif
146
147#if !EXPORTER && !IMPORTER && !FIRST_PASS
148
149 internal override object GetValue(object obj)
150 {
151 var field = GetField();
152 return FieldTypeWrapper.IsPrimitive || field == null ? GetConstantValue() : field.GetValue(null);
153 }
154
155 internal override void SetValue(object obj, object value)
156 {
157
158 }
159
160#endif
161
162 }
163
164}
IKVM.Reflection.Type Type
IKVM.Reflection.FieldInfo FieldInfo
Represents an internal error that occurred within IKVM.
MemberFlags
Describes various options applied to a member.