Check-in [25dba2477e]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Read of constant pool entries.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:25dba2477e4cb53d05646ec2cf51fd4bab0e39ee
User & Date: stephanie.gawroriski 2019-04-17 13:50:35
Context
2019-04-17
14:00
Pool data is read. check-in: 838a415bd9 user: stephanie.gawroriski tags: trunk
13:50
Read of constant pool entries. check-in: 25dba2477e user: stephanie.gawroriski tags: trunk
12:24
Base for loading of pool entries. check-in: 3a1b4cb8b5 user: stephanie.gawroriski tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/mini/MinimizedPool.java.

5
6
7
8
9
10
11





12
13
14
15
16








17
18
19
20
21
22
23
..
40
41
42
43
44
45
46
47
48

49
50
51
52




53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99




100
101
102
103
104
105
106
107






















































































































108
109
110

111








112
113
114
115
116
117
118
119
120
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package dev.shadowtail.classfile.mini;






import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import net.multiphasicapps.classfile.InvalidClassFormatException;









/**
 * This represents the minimized constant pool.
 *
 * @since 2019/04/16
 */
public final class MinimizedPool
................................................................................
	public static final MinimizedPool decode(int __n, byte[] __is, int __o,
		int __l)
		throws InvalidClassFormatException, IOException, NullPointerException
	{
		if (__is == null)
			throw new NullPointerException("NARG");
		
		DataInputStream dis = new DataInputStream(
			new ByteArrayInputStream(__is, __o, __l));

		
		// Debug
		todo.DEBUG.note("Decode %d (%d bytes)", __n, __l);
		




		// Read type table
		byte[] types = new byte[__n];
		dis.readFully(types);
		
		// Skip padding?
		if ((__n & 1) != 0)
			dis.read();
		
		// Read offsets into the structure
		int[] offsets = new int[__n];
		for (int i = 0; i < __n; i++)
			offsets[i] = dis.readUnsignedShort();
		
		// Read of all the various entries
		for (int i = 0; i < __n; i++)
			todo.DEBUG.note("%3d: %02x (@%d)", i,
				(types[i] & 0xFF), offsets[i]);

		
		// Output pool entry types, values, and parts
		int[][] parts = new int[__n][];
		Object[] values = new Object[__n];
		
		// Zero int for empty parts
		int[] nopart = new int[0];
		
		// Re-build individual pool entries
		Object[] entries = new Object[__n];
		for (int i = 0; i < __n; i++)
		{
			// Get type and pointer
			int rawtype = types[i],
				ptr = offsets[i];
			
			// Is this wide?
			boolean iswide;
			if ((iswide = ((rawtype & 0x80) != 0)))
			{
				rawtype &= 0x7F;
				
				// Re-adjust type array since we use this for the type list
				types[i] = (byte)rawtype;
			}
			
			// Read info
			int[] part = null;
			Object v = null;
			




			// Depends on the type
			MinimizedPoolEntryType type = MinimizedPoolEntryType.of(rawtype);
			switch (type)
			{
					// Null is nothing, so do not bother
				case NULL:
					break;
				






















































































































				default:
					throw new todo.OOPS(type.name());
			}

			








			// Set data
			parts[i] = (part == null ? nopart : part);
			values[i] = v;
		}
		
		throw new todo.TODO();
	}
}








>
>
>
>
>





>
>
>
>
>
>
>
>







 







|
|
>




>
>
>
>
|
<
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
>













|




|

|


|






>
>
>
>
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
|
>
>
>
>
>
>
>
>









5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package dev.shadowtail.classfile.mini;

import dev.shadowtail.classfile.nncc.AccessedField;
import dev.shadowtail.classfile.nncc.FieldAccessTime;
import dev.shadowtail.classfile.nncc.FieldAccessType;
import dev.shadowtail.classfile.nncc.InvokedMethod;
import dev.shadowtail.classfile.xlate.InvokeType;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import net.multiphasicapps.classfile.InvalidClassFormatException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ClassNames;
import net.multiphasicapps.classfile.FieldDescriptor;
import net.multiphasicapps.classfile.FieldName;
import net.multiphasicapps.classfile.FieldReference;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodHandle;
import net.multiphasicapps.classfile.MethodName;

/**
 * This represents the minimized constant pool.
 *
 * @since 2019/04/16
 */
public final class MinimizedPool
................................................................................
	public static final MinimizedPool decode(int __n, byte[] __is, int __o,
		int __l)
		throws InvalidClassFormatException, IOException, NullPointerException
	{
		if (__is == null)
			throw new NullPointerException("NARG");
		
		// Types and offsets
		byte[] types = new byte[__n];
		int[] offsets = new int[__n];
		
		// Debug
		todo.DEBUG.note("Decode %d (%d bytes)", __n, __l);
		
		// Read the type and offset table
		try (DataInputStream dis = new DataInputStream(
			new ByteArrayInputStream(__is, __o, __l)))
		{
			// Read type table

			dis.readFully(types);
			
			// Skip padding?
			if ((__n & 1) != 0)
				dis.read();
			
			// Read offsets into the structure

			for (int i = 0; i < __n; i++)
				offsets[i] = dis.readUnsignedShort();
			
			// Read of all the various entries
			for (int i = 0; i < __n; i++)
				todo.DEBUG.note("%3d: %02x (@%d)", i,
					(types[i] & 0xFF), offsets[i]);
		}
		
		// Output pool entry types, values, and parts
		int[][] parts = new int[__n][];
		Object[] values = new Object[__n];
		
		// Zero int for empty parts
		int[] nopart = new int[0];
		
		// Re-build individual pool entries
		Object[] entries = new Object[__n];
		for (int i = 0; i < __n; i++)
		{
			// Get type and pointer
			int rtype = types[i],
				ptr = offsets[i];
			
			// Is this wide?
			boolean iswide;
			if ((iswide = ((rtype & 0x80) != 0)))
			{
				rtype &= 0x7F;
				
				// Re-adjust type array since we use this for the type list
				types[i] = (byte)rtype;
			}
			
			// Read info
			int[] part = null;
			Object v = null;
			
			// It is easier to handle this as a stream of bytes
			try (DataInputStream dis = new DataInputStream(
				new ByteArrayInputStream(__is, __o + ptr, __l - ptr)))
			{
				// Depends on the type
				MinimizedPoolEntryType type = MinimizedPoolEntryType.of(rtype);
				switch (type)
				{
						// Null is nothing, so do not bother
					case NULL:
						break;
						
						// Strings
					case STRING:
						part = new int[]{
								dis.readUnsignedShort(),
								dis.readUnsignedShort(),
							};
						v = dis.readUTF();
						break;
						
						// Integer
					case INTEGER:
						v = dis.readInt();
						break;
						
						// Long
					case LONG:
						v = dis.readLong();
						break;
						
						// Float
					case FLOAT:
						v = Float.intBitsToFloat(dis.readInt());
						break;
						
						// Double
					case DOUBLE:
						v = Double.longBitsToDouble(dis.readLong());
						break;
						
						// Types which consist of parts
					case CLASS_NAME:
					case CLASS_NAMES:
					case ACCESSED_FIELD:
					case FIELD_DESCRIPTOR:
					case INVOKED_METHOD:
					case METHOD_DESCRIPTOR:
						// Wide parts
						if (iswide)
						{
							// Read length
							int np = dis.readUnsignedShort();
							
							// Read values
							part = new int[np];
							for (int j = 0; j < np; j++)
								part[j] = dis.readUnsignedShort();
						}
						
						// Narrow parts
						else
						{
							// Read length
							int np = dis.readUnsignedByte();
							
							// Read values
							part = new int[np];
							for (int j = 0; j < np; j++)
								part[j] = dis.readUnsignedByte();
						}
						
						// Now that the parts were read, we can build the
						// actual value
						switch (type)
						{
								// Class name
							case CLASS_NAME:
								v = new ClassName((String)values[part[0]]);
								break;
								
								// Names of classes
							case CLASS_NAMES:
								{
									// Read class count
									int ncn = part[0];
									
									// Read class names
									ClassName[] names = new ClassName[ncn];
									for (int j = 0, k = 1; j < ncn; j++, k++)
										names[j] = (ClassName)values[part[k]];
									
									// Build names
									v = new ClassNames(names);
								}
								break;
								
								// Field which was accessed
							case ACCESSED_FIELD:
								v = new AccessedField(
									FieldAccessTime.of(part[0]),
									FieldAccessType.of(part[1]),
									new FieldReference(
										(ClassName)values[part[2]],
										new FieldName((String)values[part[3]]),
										((ClassName)values[part[4]]).field()));
								break;
								
								// Field descriptor
							case FIELD_DESCRIPTOR:
								v = ((ClassName)values[part[0]]).field();
								break;
								
								// Invoked method
							case INVOKED_METHOD:
								v = new InvokedMethod(
									InvokeType.of(part[0]),
									new MethodHandle(
										(ClassName)values[part[1]],
										new MethodName(
											(String)values[part[2]]),
										(MethodDescriptor)values[part[3]]));
								break;
							
								// Method descriptor
							case METHOD_DESCRIPTOR:
								v = new MethodDescriptor(
									(String)values[part[0]]);
								break;
								
							default:
								throw new todo.OOPS(type.name());
						}
						break;
					
					default:
						throw new todo.OOPS(type.name());
				}
			}
			
			// Debug
			todo.DEBUG.note("Read %s", v);
			
			// Set data
			parts[i] = (part == null ? nopart : part);
			values[i] = v;
		}
		
		throw new todo.TODO();
	}
}

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/mini/MinimizedPoolBuilder.java.

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
				this.add(v.name()),
				this.add(v.descriptor()));
		}*/
		
		// String
		else if (__v instanceof String)
			return this.__add(__v,
				__v.hashCode(),
				((String)__v).length());
		
		// Primitives
		else if (__v instanceof Integer ||
			__v instanceof Long ||
			__v instanceof Float ||
			__v instanceof Double)







|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
				this.add(v.name()),
				this.add(v.descriptor()));
		}*/
		
		// String
		else if (__v instanceof String)
			return this.__add(__v,
				__v.hashCode() & 0xFFFF,
				((String)__v).length());
		
		// Primitives
		else if (__v instanceof Integer ||
			__v instanceof Long ||
			__v instanceof Float ||
			__v instanceof Double)

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/nncc/FieldAccessTime.java.

21
22
23
24
25
26
27
28


29



















	INITIALIZER,
	
	/** Normal non-constructor access. */
	NORMAL,
	
	/** End. */
	;
}





























|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	INITIALIZER,
	
	/** Normal non-constructor access. */
	NORMAL,
	
	/** End. */
	;
	
	/**
	 * Returns the access time for the given ordinal.
	 *
	 * @param __i The ordinal.
	 * @return The access time.
	 * @throws IllegalArgumentException If it is not valid.
	 * @since 2019/04/17
	 */
	public static final FieldAccessTime of(int __i)
		throws IllegalArgumentException
	{
		switch (__i)
		{
			case 0:	return INITIALIZER;
			case 1: return NORMAL;
		}
		
		// {@squirreljme.error JC3u Unknown access time. (The index)}
		throw new IllegalArgumentException("JC3u " + __i);
	}
}

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/nncc/FieldAccessType.java.

21
22
23
24
25
26
27
28


29



















	STATIC,
	
	/** Instance. */
	INSTANCE,
	
	/** End. */
	;
}





























|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	STATIC,
	
	/** Instance. */
	INSTANCE,
	
	/** End. */
	;
	
	/**
	 * Returns the access type for the given ordinal.
	 *
	 * @param __i The ordinal.
	 * @return The access type.
	 * @throws IllegalArgumentException If it is not valid.
	 * @since 2019/04/17
	 */
	public static final FieldAccessType of(int __i)
		throws IllegalArgumentException
	{
		switch (__i)
		{
			case 0:	return STATIC;
			case 1: return INSTANCE;
		}
		
		// {@squirreljme.error JC3v Unknown access type. (The index)}
		throw new IllegalArgumentException("JC3v " + __i);
	}
}

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/nncc/NativeInstruction.java.

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
				// [p16, reglist]
			case NativeInstructionType.INVOKE:
				return ArgumentFormat.of(
					ArgumentFormat.VPOOL,
					ArgumentFormat.REGLIST);
		}
		
		// {@squirreljme.error JC3r Invalid operation. (The operation)}
		throw new IllegalArgumentException("JC3r " +
			NativeInstruction.mnemonic(__op));
	}
	
	/**
	 * Returns the encoding of the given instruction.
	 *
	 * @param __op The operation to get the encoding of.







|
|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
				// [p16, reglist]
			case NativeInstructionType.INVOKE:
				return ArgumentFormat.of(
					ArgumentFormat.VPOOL,
					ArgumentFormat.REGLIST);
		}
		
		// {@squirreljme.error JC3t Invalid operation. (The operation)}
		throw new IllegalArgumentException("JC3t " +
			NativeInstruction.mnemonic(__op));
	}
	
	/**
	 * Returns the encoding of the given instruction.
	 *
	 * @param __op The operation to get the encoding of.

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/xlate/InvokeType.java.

38
39
40
41
42
43
44
45


46





















	 * @return If there is an instance variable that is used.
	 * @since 2019/03/20
	 */
	public final boolean hasInstance()
	{
		return this != STATIC;
	}
}































|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
	 * @return If there is an instance variable that is used.
	 * @since 2019/03/20
	 */
	public final boolean hasInstance()
	{
		return this != STATIC;
	}
	
	/**
	 * Returns the invocation type for the given ordinal.
	 *
	 * @param __i The ordinal.
	 * @return The invocation type.
	 * @throws IllegalArgumentException If it is not valid.
	 * @since 2019/04/17
	 */
	public static final InvokeType of(int __i)
		throws IllegalArgumentException
	{
		switch (__i)
		{
			case 0:	return STATIC;
			case 1: return SPECIAL;
			case 2: return VIRTUAL;
			case 3: return INTERFACE;
		}
		
		// {@squirreljme.error JC3w Unknown invocation type. (The index)}
		throw new IllegalArgumentException("JC3w " + __i);
	}
}