Check-in [5bd3e800ba]

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

Overview
Comment:Refactor the minimizer to use the new table section output as it is easier to manage.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:5bd3e800baa6318351ea206fa0f3091e3a8952d3
User & Date: stephanie.gawroriski 2019-08-11 15:16:20
Context
2019-08-11
15:40
Implement some base methods for writing data. check-in: 8312e39f0f user: stephanie.gawroriski tags: trunk
15:16
Refactor the minimizer to use the new table section output as it is easier to manage. check-in: 5bd3e800ba user: stephanie.gawroriski tags: trunk
14:28
Just make the variable length the minimum value. check-in: 34669358f3 user: stephanie.gawroriski tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to runt/libs/io/net/multiphasicapps/io/TableSectionOutputStream.java.

37
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
..
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
...
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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
...
369
370
371
372
373
374
375
























376
377
378
379
380
381
382
...
446
447
448
449
450
451
452


































































































453
454
455
456
457
458
459
	
	/**
	 * Adds a section which is of a variable size.
	 *
	 * @return The resulting section.
	 * @since 2019/08/11
	 */
	public final Section addSection()
	{
		return this.addSection(VARIABLE_SIZE, 0);
	}











































	
	/**
	 * Adds a section which is either of a variable size of a fixed size.
	 *
	 * @param __size The size of the section to use, if {@link #VARIABLE_SIZE}
	 * then the section will have a variable size.
	 * @return The section which was created for writing.
	 * @throws IllegalArgumentException If the size is zero or negative and
	 * is not the variable size.
	 * @since 2019/08/11
	 */
	public final Section addSection(int __size)
		throws IllegalArgumentException
	{
		return this.addSection(__size, 0);
	}
	
	/**
	 * Adds a section which is either of a variable size of a fixed size and
................................................................................
	 * @param __align The alignment of the section, if the value is lower than
	 * {@code 1} it will be set to {@code 1}.
	 * @return The section which was created for writing.
	 * @throws IllegalArgumentException If the size is zero or negative and
	 * is not the variable size.
	 * @since 2019/08/11
	 */
	public final Section addSection(int __size, int __align)

		throws IllegalArgumentException
	{
		// {@squirreljme.error BD3h Zero or negative size section. (The size)}
		if (__size != VARIABLE_SIZE && __size <= 0)
			throw new IllegalArgumentException("BD3h " + __size);
		
		// It does not make sense to align under a byte
................................................................................
				throw new NullPointerException("NARG");
			if (__o < 0 || __l < 0 || (__o + __l) > __b.length)
				throw new IndexOutOfBoundsException("IOOB");
			
			throw new todo.TODO();
		}
		
		/**
		 * Writes the address of the given section as an integer.
		 *
		 * @param __s The section to write the address of.
		 * @throws IOException On write errors.
		 * @throws NullPointerException On null arguments.
		 * @since 2019/08/11
		 */
		public final void writeAddressInt(Section __s)
			throws IOException, NullPointerException
		{
			if (__s == null)
				throw new NullPointerException("NARG");
			
			throw new todo.TODO();
		}
		
		/**
		 * Writes the address of the given section as a short.
		 *
		 * @param __s The section to write the address of.
		 * @throws IOException On write errors.
		 * @throws NullPointerException On null arguments.
		 * @since 2019/08/11
		 */
		public final void writeAddressShort(Section __s)
			throws IOException, NullPointerException
		{
			if (__s == null)
				throw new NullPointerException("NARG");
			
			throw new todo.TODO();
		}
		
		/**
		 * Writes padding which aligns to a given amount from within the
		 * data stream as itself.
		 *
		 * @param __n The number of bytes to align to.
		 * @return The number of alignment bytes written.
		 * @throws IllegalArgumentException If the requested alignment is
................................................................................
		 */
		@Override
		public final void writeDouble(double __v)
			throws IOException
		{
			throw new todo.TODO();
		}
























		
		/**
		 * {@inheritDoc}
		 * @since 2019/08/11
		 */
		@Override
		public final void writeFloat(float __v)
................................................................................
		/**
		 * {@inheritDoc}
		 * @since 2019/08/11
		 */
		@Override
		public final void writeShort(int __v)
			throws IOException


































































































		{
			throw new todo.TODO();
		}
		
		/**
		 * {@inheritDoc}
		 * @since 2019/08/11







|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|







 







|
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







37
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
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
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
288
289
290
291
292
293
294


































295
296
297
298
299
300
301
...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
	
	/**
	 * Adds a section which is of a variable size.
	 *
	 * @return The resulting section.
	 * @since 2019/08/11
	 */
	public final TableSectionOutputStream.Section addSection()
	{
		return this.addSection(VARIABLE_SIZE, 0);
	}
	
	/**
	 * Adds a section which consists of the given byte array.
	 *
	 * @param __bytes The byte array to initialize as.
	 * @return The resulting section.
	 * @throws IOException If the section could not be written.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/08/11
	 */
	public final TableSectionOutputStream.Section addSection(byte[] __bytes)
		throws IOException, NullPointerException
	{
		return this.addSection(__bytes, 0);
	}
	
	/**
	 * Adds a section which consists of the given byte array using the given
	 * alignment.
	 *
	 * @param __bytes The byte array to initialize as.
	 * @param __align The alignment to use.
	 * @return The resulting section.
	 * @throws IOException If the section could not be written.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/08/11
	 */
	public final TableSectionOutputStream.Section addSection(byte[] __bytes,
		int __align)
		throws IOException, NullPointerException
	{
		if (__bytes == null)
			throw new NullPointerException("NARG");
		
		// Add new section
		Section rv = this.addSection(__bytes.length, __align);
		
		// Write all the bytes into it
		rv.write(__bytes);
		
		// Use this section
		return rv;
	}
	
	/**
	 * Adds a section which is either of a variable size of a fixed size.
	 *
	 * @param __size The size of the section to use, if {@link #VARIABLE_SIZE}
	 * then the section will have a variable size.
	 * @return The section which was created for writing.
	 * @throws IllegalArgumentException If the size is zero or negative and
	 * is not the variable size.
	 * @since 2019/08/11
	 */
	public final TableSectionOutputStream.Section addSection(int __size)
		throws IllegalArgumentException
	{
		return this.addSection(__size, 0);
	}
	
	/**
	 * Adds a section which is either of a variable size of a fixed size and
................................................................................
	 * @param __align The alignment of the section, if the value is lower than
	 * {@code 1} it will be set to {@code 1}.
	 * @return The section which was created for writing.
	 * @throws IllegalArgumentException If the size is zero or negative and
	 * is not the variable size.
	 * @since 2019/08/11
	 */
	public final TableSectionOutputStream.Section addSection(int __size,
		int __align)
		throws IllegalArgumentException
	{
		// {@squirreljme.error BD3h Zero or negative size section. (The size)}
		if (__size != VARIABLE_SIZE && __size <= 0)
			throw new IllegalArgumentException("BD3h " + __size);
		
		// It does not make sense to align under a byte
................................................................................
				throw new NullPointerException("NARG");
			if (__o < 0 || __l < 0 || (__o + __l) > __b.length)
				throw new IndexOutOfBoundsException("IOOB");
			
			throw new todo.TODO();
		}
		


































		/**
		 * Writes padding which aligns to a given amount from within the
		 * data stream as itself.
		 *
		 * @param __n The number of bytes to align to.
		 * @return The number of alignment bytes written.
		 * @throws IllegalArgumentException If the requested alignment is
................................................................................
		 */
		@Override
		public final void writeDouble(double __v)
			throws IOException
		{
			throw new todo.TODO();
		}
		
		/**
		 * Writes the size of the file as an integer.
		 *
		 * @throws IOException On write errors.
		 * @since 2019/08/11
		 */
		public final void writeFileSizeInt()
			throws IOException
		{
			throw new todo.TODO();
		}
		
		/**
		 * Writes the size of the file as a short.
		 *
		 * @throws IOException On write errors.
		 * @since 2019/08/11
		 */
		public final void writeFileSizeShort()
			throws IOException
		{
			throw new todo.TODO();
		}
		
		/**
		 * {@inheritDoc}
		 * @since 2019/08/11
		 */
		@Override
		public final void writeFloat(float __v)
................................................................................
		/**
		 * {@inheritDoc}
		 * @since 2019/08/11
		 */
		@Override
		public final void writeShort(int __v)
			throws IOException
		{
			throw new todo.TODO();
		}
		
		/**
		 * Writes the address of the given section as an integer.
		 *
		 * @param __s The section to write the address of.
		 * @throws IOException On write errors.
		 * @throws NullPointerException On null arguments.
		 * @since 2019/08/11
		 */
		public final void writeSectionAddressInt(Section __s)
			throws IOException, NullPointerException
		{
			if (__s == null)
				throw new NullPointerException("NARG");
			
			throw new todo.TODO();
		}
		
		/**
		 * Writes the address of the given section as a short.
		 *
		 * @param __s The section to write the address of.
		 * @throws IOException On write errors.
		 * @throws NullPointerException On null arguments.
		 * @since 2019/08/11
		 */
		public final void writeSectionAddressShort(Section __s)
			throws IOException, NullPointerException
		{
			if (__s == null)
				throw new NullPointerException("NARG");
			
			throw new todo.TODO();
		}
		
		/**
		 * Writes the size of the given section as an integer.
		 *
		 * @param __s The section and its size to write.
		 * @throws IOException On write errors.
		 * @throws NullPointerException On null arguments.
		 * @since 2019/08/11
		 */
		public final void writeSectionSizeInt(Section __s)
			throws IOException, NullPointerException
		{
			if (__s == null)
				throw new NullPointerException("NARG");
			
			throw new todo.TODO();
		}
		
		/**
		 * Writes the size of the given section as a short.
		 *
		 * @param __s The section and its size to write.
		 * @throws IOException On write errors.
		 * @throws NullPointerException On null arguments.
		 * @since 2019/08/11
		 */
		public final void writeSectionSizeShort(Section __s)
			throws IOException, NullPointerException
		{
			if (__s == null)
				throw new NullPointerException("NARG");
			
			throw new todo.TODO();
		}
		
		/**
		 * Writes the specified short value and checks to make sure it is
		 * within the range of a short.
		 *
		 * @param __v The value to write.
		 * @throws IOException If the short could not be written or it
		 * exceeds the range of a short value.
		 * @since 2019/08/11
		 */
		public final void writeShortChecked(int __v)
			throws IOException
		{
			throw new todo.TODO();
		}
		
		/**
		 * Writes the specified unsigned short value and checks to make sure it
		 * is within the range of an unsigned short.
		 *
		 * @param __v The value to write.
		 * @throws IOException If the unsigned short could not be written or it
		 * exceeds the range of an unsigned short value.
		 * @since 2019/08/11
		 */
		public final void writeUnsignedShortChecked(int __v)
			throws IOException
		{
			throw new todo.TODO();
		}
		
		/**
		 * {@inheritDoc}
		 * @since 2019/08/11

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

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
214
215
216
217
218
219
220


221
222
223
224
225
226
227
228
...
303
304
305
306
307
308
309


310
311
312
313
314
315
316
317
318
319
	
	/** Low bits for UUID. */
	public final int uuidlo;
	
	/** File size. */
	public final int filesize;
	
	/** Size of all the non-header data. */
	public final int datasize;
	
	/** Static constant pool offset. */
	public final int staticpooloff;
	
	/** Static constant pool size. */
	public final int staticpoolsize;
	
................................................................................
		
		// UUID
		this.uuidhi = __vx[at++];
		this.uuidlo = __vx[at++];
			
		// File size
		this.filesize = __vx[at++];


		this.datasize = __vx[at++];
		
		// Static and run-time constant pool
		this.staticpooloff = __vx[at++];
		this.staticpoolsize = __vx[at++];
		this.runtimepooloff = __vx[at++];
		this.runtimepoolsize = __vx[at++];
	}
................................................................................
			
			// UUID
			/* uuidhi */ dis.readInt(),
			/* uuidlo */ dis.readInt(),
			
			// File size
			/* filesize */ dis.readInt(),


			/* datasize */ dis.readInt(),
			
			// Static and runtime pool
			/* staticpooloff */ dis.readInt(),
			/* staticpoolsize */ dis.readInt(),
			/* runtimepooloff */ dis.readInt(),
			/* runtimepoolsize */ dis.readInt());
	}	
}








|
|







 







>
>
|







 







>
>
|









134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	
	/** Low bits for UUID. */
	public final int uuidlo;
	
	/** File size. */
	public final int filesize;
	
	/** Unused B. */
	public final int unusedb;
	
	/** Static constant pool offset. */
	public final int staticpooloff;
	
	/** Static constant pool size. */
	public final int staticpoolsize;
	
................................................................................
		
		// UUID
		this.uuidhi = __vx[at++];
		this.uuidlo = __vx[at++];
			
		// File size
		this.filesize = __vx[at++];
		
		// Not used
		this.unusedb = __vx[at++];
		
		// Static and run-time constant pool
		this.staticpooloff = __vx[at++];
		this.staticpoolsize = __vx[at++];
		this.runtimepooloff = __vx[at++];
		this.runtimepoolsize = __vx[at++];
	}
................................................................................
			
			// UUID
			/* uuidhi */ dis.readInt(),
			/* uuidlo */ dis.readInt(),
			
			// File size
			/* filesize */ dis.readInt(),
			
			// Unused
			/* unusedb */ dis.readInt(),
			
			// Static and runtime pool
			/* staticpooloff */ dis.readInt(),
			/* staticpoolsize */ dis.readInt(),
			/* runtimepooloff */ dis.readInt(),
			/* runtimepoolsize */ dis.readInt());
	}	
}

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

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
			throw new IllegalStateException("JC3q " + __v);
		return rv;
	}
	
	/**
	 * Returns the byte representation of the data here.
	 *
	 * @param __methods Methods for lookup, used to find the where oart.
	 * @return The byte data representation.
	 * @since 2019/04/14
	 */
	public final byte[] getBytes(__TempMethods__[] __methods)
		throws NullPointerException
	{
		if (__methods == null)
			throw new NullPointerException("NARG");
		
		Map<Object, Integer> pool = this._pool;
		List<int[]> parts = this._parts;
		
		// Write data
		try
		{
			// Table type information







<



|
<

<
<
<







255
256
257
258
259
260
261

262
263
264
265

266



267
268
269
270
271
272
273
			throw new IllegalStateException("JC3q " + __v);
		return rv;
	}
	
	/**
	 * Returns the byte representation of the data here.
	 *

	 * @return The byte data representation.
	 * @since 2019/04/14
	 */
	public final byte[] getBytes()

	{



		Map<Object, Integer> pool = this._pool;
		List<int[]> parts = this._parts;
		
		// Write data
		try
		{
			// Table type information

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

43
44
45
46
47
48
49

50
51
52
53
54
55
56
..
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
...
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
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319



320
321
322
323
324
325
326
...
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
...
879
880
881
882
883
884
885

886
887
888
889
890
891
892
...
898
899
900
901
902
903
904

905
906
907
908
909
910
911
...
966
967
968
969
970
971
972

973
974
975
976
977
978
979
...
985
986
987
988
989
990
991

992
993
994
995
996
997
998
import net.multiphasicapps.classfile.InstructionJumpTarget;
import net.multiphasicapps.classfile.InvalidClassFormatException;
import net.multiphasicapps.classfile.Method;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodFlags;
import net.multiphasicapps.classfile.MethodName;
import net.multiphasicapps.classfile.PrimitiveType;


/**
 * This takes an input class file and translates it to the minimized format
 * which is easier to use.
 *
 * @since 2019/03/10
 */
................................................................................
				(__dp = new DualClassRuntimePoolBuilder()) : __dp));
		this.dualpool = __dp;
	}
	
	/**
	 * Performs the minimization process.
	 *
	 * @param __dos The stream to write the result to.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/03/10
	 */
	private final void __run(DataOutputStream __dos)
		throws IOException, NullPointerException
	{
		if (__dos == null)
			throw new NullPointerException("NARG");
			

		ClassFile input = this.input;
		



		// {@squirreljme.error JC0g Class name string was not the first entry
		// in the pool.}
		int pidx;
		MinimizedPoolBuilder pool = this.pool;
		if (1 != (pidx = pool.add(input.thisName().toString())))
			throw new IllegalArgumentException("JC0g " + pidx);
		
................................................................................
			// to the current class pool
			// {@squirreljme.error JC0i Reference to the current class pool was
			// not the third entry of the pool.}
			if (3 != (pidx = pool.add(new ClassPool(input.thisName()))))
				throw new IllegalArgumentException("JC0i " + pidx);
		}
		
		// Write magic number to specify this format
		__dos.writeInt(MinimizedClassHeader.MAGIC_NUMBER);
		
		// Process all fields
		__TempFields__[] fields = this.__doFields(); 

		


		// Process all methods
		__TempMethods__[] methods = this.__doMethods();
		



		// Unused, may be used later when needed
		__dos.writeShort(0);
		
		// The index of the instance method named __start
		int startdx = 0;
		for (MinimizedMethod mm : methods[1]._methods)

		{
			if (mm.name.toString().equals("__start"))
				break;
			startdx++;
		}
		__dos.writeByte(startdx);
		
		// Data type of the class
		__dos.writeByte(DataType.of(input.thisName().field()).ordinal());
		
		// This may be null for Object
		ClassName supernamecn = input.superName();
		
		// Class names
		int thisname = pool.add(input.thisName()),
			supername = (supernamecn == null ? 0 : pool.add(supernamecn)),
			inames = pool.add(input.interfaceNames());
		
		// The source file name
		String sfn = input.sourceFile();
		int snfid = (sfn == null ? 0 : Minimizer.__checkUShort(pool.add(sfn)));
		
		// Store the pool size
		__dos.writeShort(Minimizer.__checkUShort(pool.size()));
		
		// Store class information, such as the flags, name, superclass,
		// interfaces, class type, and version
		__dos.writeInt(input.flags().toJavaBits());
		__dos.writeShort(Minimizer.__checkUShort(thisname));
		__dos.writeShort(Minimizer.__checkUShort(supername));
		__dos.writeShort(Minimizer.__checkUShort(inames));
		__dos.writeByte(input.type().ordinal());
		__dos.writeByte(input.version().ordinal());
		
		// Needed for debugging to figure out what file the class is in,
		// will be very useful
		__dos.writeShort(snfid);
		
		// Write static and instance field counts
		for (int i = 0; i < 2; i++)
		{
			__TempFields__ tf = fields[i];
			
			__dos.writeShort(Minimizer.__checkUShort(tf._count));
			__dos.writeShort(Minimizer.__checkUShort((tf._bytes + 3) & (~3)));
			__dos.writeShort(Minimizer.__checkUShort(tf._objects));
		}
		
		// Write static and instance method counts
		for (int i = 0; i < 2; i++)
		{
			__TempMethods__ tm = methods[i];
			
			__dos.writeShort(Minimizer.__checkUShort(tm._count));
		}
		
		// Relative offset where all the data will end up being, starts at
		// the constant pool address.
		int reloff = MinimizedClassHeader.HEADER_SIZE_WITH_MAGIC,
			baserel = reloff;
		
		// Base round to pool data
		reloff = Minimizer.__relAdd(reloff, 0);
		byte[] pooldata = pool.getBytes(methods);
		
		// Constant pool locator
		__dos.writeInt(reloff);
		__dos.writeInt(pooldata.length);


		
		// Round
		reloff = Minimizer.__relAdd(reloff, pooldata.length);
		
		// Field locator
		byte[][] fielddata = new byte[2][];
		for (int i = 0; i < 2; i++)
		{
			__TempFields__ tf = fields[i];



			
			// Get bytes
			byte[] data = tf.getBytes(pool);
			fielddata[i] = data;
			
			// Offset and size
			__dos.writeInt(reloff);
			__dos.writeInt(data.length);
			
			// Round
			reloff = Minimizer.__relAdd(reloff, data.length);



		}
		
		// Method locator
		byte[][] methoddata = new byte[2][];
		for (int i = 0; i < 2; i++)
		{

			__TempMethods__ tm = methods[i];

			
			// Get bytes
			byte[] data = tm.getBytes(pool);
			methoddata[i] = data;
			
			// Offset and size
			__dos.writeInt(reloff);
			__dos.writeInt(data.length);
			
			// Round
			reloff = Minimizer.__relAdd(reloff, data.length);

		}
		
		// Generate a UUID and write it
		long uuid = Minimizer.generateUUID();
		__dos.writeInt((int)(uuid >>> 32));
		__dos.writeInt((int)uuid);
		
		// Write absolute file size! This saves time in calculating how big
		// a file we have and we can just read that many bytes for all the
		// data areas or similar if needed
		__dos.writeInt(reloff + 4);
		__dos.writeInt((reloff - baserel) + 4);
		

		// Round for the pools
		reloff = Minimizer.__relAdd(reloff, 0);
		
		// Static pool offset and size
		__dos.writeInt(0);
		__dos.writeInt(0);
		
		// Runtime pool offset and size
		__dos.writeInt(0);
		__dos.writeInt(0);
		
		// Constant pool is rounded
		Minimizer.__dosRound(__dos);
		
		// Write constant pool
		__dos.write(pooldata);
		Minimizer.__dosRound(__dos);
		
		// Write field data
		for (int i = 0; i < 2; i++)
		{
			__dos.write(fielddata[i]);
			Minimizer.__dosRound(__dos);
		}
		
		// Write method data
		for (int i = 0; i < 2; i++)
		{
			__dos.write(methoddata[i]);
			Minimizer.__dosRound(__dos);
		}
		
		// Write end magic number
		__dos.writeInt(MinimizedClassHeader.END_MAGIC_NUMBER);



	}
	
	/**
	 * Process fields.
	 *
	 * @return The resulting fields, static and instance split into each.
	 * @since 2019/03/11
................................................................................
	public static final void minimize(DualClassRuntimePoolBuilder __dp,
		ClassFile __cf, OutputStream __os)
		throws InvalidClassFormatException, IOException, NullPointerException
	{
		if (__cf == null || __os == null)
			throw new NullPointerException("NARG");
		
		new Minimizer(__dp, __cf).__run(new DataOutputStream(__os));
	}
	
	/**
	 * Minimizes the given class and returns the minimized version of it.
	 *
	 * @param __cf The class to minimize.
	 * @return The resulting minimized class.
................................................................................
	 * Checks that the unsigned short is in range.
	 *
	 * @param __v The value to check.
	 * @return {@code __v}.
	 * @throws InvalidClassFormatException If the short is out of range.
	 * @since 2019/04/14
	 */

	static final int __checkUShort(int __v)
		throws InvalidClassFormatException
	{
		// {@squirreljme.error JC0o Unsigned short out of range. (The value)}
		if (__v < 0 || __v > 65535)
			throw new InvalidClassFormatException("JC0o " + __v);
		return __v;
................................................................................
	 * @param __st The input table.
	 * @param __bt The byte table.
	 * @return The resulting RLE encoded byte data.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/03/24
	 */

	private static final byte[] __compact(short[] __st, byte[] __bt)
		throws IOException, NullPointerException
	{
		if (__st == null && __bt == null)
			throw new NullPointerException("NARG");
		
		// Using shorts or bytes
................................................................................
	 *
	 * @param __dos The stream to pad.
	 * @return The current size of the output stream.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/04/14
	 */

	static final int __dosRound(DataOutputStream __dos)
		throws IOException, NullPointerException
	{
		if (__dos == null)
			throw new NullPointerException("NARG");
		
		// Add padding
................................................................................
	/**
	 * Adds length data to the relative offset.
	 *
	 * @param __rel Current relative offset.
	 * @param __v The offset to add.
	 * @since 2019/04/14
	 */

	static final int __relAdd(int __rel, int __v)
	{
		__rel += __v;
		return (__rel + 3) & (~3);
	}
}








>







 







|




|


|


>


>
>
>







 







<
<
<
|
|
>

>
>
|
<

>
>
>

|


<
<
>
|
<
<
<
<
<
<

|











|


|



|
|
|
|
|
|



|






|
|
|







|


|
|
|
<

<
<
<
<

<
<
>
>

<
<
<

<


<
>
>
>

<
<
<
<
<
<
<
<
<
<
>
>
>



<


>
|
>

<
|
|
<
<
<
<
<
<
<
>




|
|




|
<

>
|
<


|
|


|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
>
>
>







 







|







 







>







 







>







 







>







 







>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
..
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
...
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
269
270
271
272
273
274
275





















276
277
278
279
280
281
282
283
284
285
286
287
...
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
...
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
...
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
...
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
...
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
import net.multiphasicapps.classfile.InstructionJumpTarget;
import net.multiphasicapps.classfile.InvalidClassFormatException;
import net.multiphasicapps.classfile.Method;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodFlags;
import net.multiphasicapps.classfile.MethodName;
import net.multiphasicapps.classfile.PrimitiveType;
import net.multiphasicapps.io.TableSectionOutputStream;

/**
 * This takes an input class file and translates it to the minimized format
 * which is easier to use.
 *
 * @since 2019/03/10
 */
................................................................................
				(__dp = new DualClassRuntimePoolBuilder()) : __dp));
		this.dualpool = __dp;
	}
	
	/**
	 * Performs the minimization process.
	 *
	 * @param __os The stream to write the result to.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/03/10
	 */
	private final void __run(OutputStream __os)
		throws IOException, NullPointerException
	{
		if (__os == null)
			throw new NullPointerException("NARG");
			
		// The input class
		ClassFile input = this.input;
		
		// The output section
		TableSectionOutputStream output = new TableSectionOutputStream();
		
		// {@squirreljme.error JC0g Class name string was not the first entry
		// in the pool.}
		int pidx;
		MinimizedPoolBuilder pool = this.pool;
		if (1 != (pidx = pool.add(input.thisName().toString())))
			throw new IllegalArgumentException("JC0g " + pidx);
		
................................................................................
			// to the current class pool
			// {@squirreljme.error JC0i Reference to the current class pool was
			// not the third entry of the pool.}
			if (3 != (pidx = pool.add(new ClassPool(input.thisName()))))
				throw new IllegalArgumentException("JC0i " + pidx);
		}
		



		// Process all fields and methods
		__TempFields__[] fields = this.__doFields();
		__TempMethods__[] methods = this.__doMethods();
		
		// Initialize header section
		TableSectionOutputStream.Section header =
			output.addSection(MinimizedClassHeader.HEADER_SIZE_WITH_MAGIC);

		
		// Write magic number to specify this format
		header.writeInt(MinimizedClassHeader.MAGIC_NUMBER);
		
		// Unused, may be used later when needed
		header.writeShort(0);
		
		// The index of the instance method named __start


		header.writeByte(methods[1].findMethodIndex("__start"));
		






		// Data type of the class
		header.writeByte(DataType.of(input.thisName().field()).ordinal());
		
		// This may be null for Object
		ClassName supernamecn = input.superName();
		
		// Class names
		int thisname = pool.add(input.thisName()),
			supername = (supernamecn == null ? 0 : pool.add(supernamecn)),
			inames = pool.add(input.interfaceNames());
		
		// The source file name
		String sfn = input.sourceFile();
		int snfid = (sfn == null ? 0 : pool.add(sfn));
		
		// Store the pool size
		header.writeUnsignedShortChecked(pool.size());
		
		// Store class information, such as the flags, name, superclass,
		// interfaces, class type, and version
		header.writeInt(input.flags().toJavaBits());
		header.writeUnsignedShortChecked(thisname);
		header.writeUnsignedShortChecked(supername);
		header.writeUnsignedShortChecked(inames);
		header.writeByte(input.type().ordinal());
		header.writeByte(input.version().ordinal());
		
		// Needed for debugging to figure out what file the class is in,
		// will be very useful
		header.writeUnsignedShortChecked(snfid);
		
		// Write static and instance field counts
		for (int i = 0; i < 2; i++)
		{
			__TempFields__ tf = fields[i];
			
			header.writeUnsignedShortChecked(tf._count);
			header.writeUnsignedShortChecked((tf._bytes + 3) & (~3));
			header.writeUnsignedShortChecked(tf._objects);
		}
		
		// Write static and instance method counts
		for (int i = 0; i < 2; i++)
		{
			__TempMethods__ tm = methods[i];
			
			header.writeUnsignedShortChecked(tm._count);
		}
		
		// Build section where the constant pool is
		TableSectionOutputStream.Section poolsection =
			output.addSection(pool.getBytes(), 4);

		




		// Constant pool locator


		header.writeSectionAddressInt(poolsection);
		header.writeSectionSizeInt(poolsection);
		



		// Field locator

		for (int i = 0; i < 2; i++)
		{

			// Generate section
			TableSectionOutputStream.Section subsection =
				output.addSection(fields[i].getBytes(pool), 4);
			










			// Write section details
			header.writeSectionAddressInt(subsection);
			header.writeSectionSizeInt(subsection);
		}
		
		// Method locator

		for (int i = 0; i < 2; i++)
		{
			// Generate section
			TableSectionOutputStream.Section subsection =
				output.addSection(methods[i].getBytes(pool), 4);
			

			// Write section details
			header.writeSectionAddressInt(subsection);







			header.writeSectionSizeInt(subsection);
		}
		
		// Generate a UUID and write it
		long uuid = Minimizer.generateUUID();
		header.writeInt((int)(uuid >>> 32));
		header.writeInt((int)uuid);
		
		// Write absolute file size! This saves time in calculating how big
		// a file we have and we can just read that many bytes for all the
		// data areas or similar if needed
		header.writeFileSizeInt();

		
		// Not used anymore
		header.writeInt(0);

		
		// Static pool offset and size
		header.writeInt(0);
		header.writeInt(0);
		
		// Runtime pool offset and size
		header.writeInt(0);
		header.writeInt(0);
		





















		// Write end magic number
		header.writeInt(MinimizedClassHeader.END_MAGIC_NUMBER);
		
		// Write resulting file
		output.writeTo(__os);
	}
	
	/**
	 * Process fields.
	 *
	 * @return The resulting fields, static and instance split into each.
	 * @since 2019/03/11
................................................................................
	public static final void minimize(DualClassRuntimePoolBuilder __dp,
		ClassFile __cf, OutputStream __os)
		throws InvalidClassFormatException, IOException, NullPointerException
	{
		if (__cf == null || __os == null)
			throw new NullPointerException("NARG");
		
		new Minimizer(__dp, __cf).__run(__os);
	}
	
	/**
	 * Minimizes the given class and returns the minimized version of it.
	 *
	 * @param __cf The class to minimize.
	 * @return The resulting minimized class.
................................................................................
	 * Checks that the unsigned short is in range.
	 *
	 * @param __v The value to check.
	 * @return {@code __v}.
	 * @throws InvalidClassFormatException If the short is out of range.
	 * @since 2019/04/14
	 */
	@Deprecated
	static final int __checkUShort(int __v)
		throws InvalidClassFormatException
	{
		// {@squirreljme.error JC0o Unsigned short out of range. (The value)}
		if (__v < 0 || __v > 65535)
			throw new InvalidClassFormatException("JC0o " + __v);
		return __v;
................................................................................
	 * @param __st The input table.
	 * @param __bt The byte table.
	 * @return The resulting RLE encoded byte data.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/03/24
	 */
	@Deprecated
	private static final byte[] __compact(short[] __st, byte[] __bt)
		throws IOException, NullPointerException
	{
		if (__st == null && __bt == null)
			throw new NullPointerException("NARG");
		
		// Using shorts or bytes
................................................................................
	 *
	 * @param __dos The stream to pad.
	 * @return The current size of the output stream.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/04/14
	 */
	@Deprecated
	static final int __dosRound(DataOutputStream __dos)
		throws IOException, NullPointerException
	{
		if (__dos == null)
			throw new NullPointerException("NARG");
		
		// Add padding
................................................................................
	/**
	 * Adds length data to the relative offset.
	 *
	 * @param __rel Current relative offset.
	 * @param __v The offset to add.
	 * @since 2019/04/14
	 */
	@Deprecated
	static final int __relAdd(int __rel, int __v)
	{
		__rel += __v;
		return (__rel + 3) & (~3);
	}
}

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

47
48
49
50
51
52
53





















54
55
56
57
58
59
60
		throws NullPointerException
	{
		if (__cn == null)
			throw new NullPointerException("NARG");
		
		this.classname = __cn;
	}





















	
	/**
	 * Returns the byte representation of the data here.
	 *
	 * @param __pool The constant pool.
	 * @return The byte data representation.
	 * @throws NullPointerException On null arguments.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
		throws NullPointerException
	{
		if (__cn == null)
			throw new NullPointerException("NARG");
		
		this.classname = __cn;
	}
	
	/**
	 * Finds the method by the given name.
	 *
	 * @param __name The name to locate.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/08/11
	 */
	public final int findMethodIndex(String __name)
		throws NullPointerException
	{
		if (__name == null)
			throw new NullPointerException("NARG");
		
		List<MinimizedMethod> methods = this._methods;
		for (int i = 0, n = methods.size(); i < n; i++)
			if (__name.equals(methods.get(i).nameAndType().name().toString()))
				return i;
		
		return -1;
	}
	
	/**
	 * Returns the byte representation of the data here.
	 *
	 * @param __pool The constant pool.
	 * @return The byte data representation.
	 * @throws NullPointerException On null arguments.