Check-in [895f1a5e6b]

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

Overview
Comment:Write of SummerCoat's config ROM area.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:895f1a5e6bc724ba43736633e296d08756980c16
User & Date: stephanie.gawroriski 2019-06-14 15:01:44
Context
2019-06-14
15:37
Add configuration ROM to RatufaCoat; Correct potential memory leak in RatufaCoat; Implement Java instruction write types in RatufaCoat check-in: e77018c3ea user: stephanie.gawroriski tags: trunk
15:01
Write of SummerCoat's config ROM area. check-in: 895f1a5e6b user: stephanie.gawroriski tags: trunk
14:37
Remove deprecated class. check-in: 0ba25e5877 user: stephanie.gawroriski tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added runt/apis/cldc-compact/cc/squirreljme/jvm/ConfigRomType.java.







































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
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
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
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm;

/**
 * This represents an option in the configuration ROM.
 *
 * @since 2019/06/14
 */
public interface ConfigRomType
{
	/** End of configuration. */
	public static final short END =
		0;
	
	/** Java VM Version. */
	public static final short JAVA_VM_VERSION =
		1;
	
	/** Java VM Name. */
	public static final short JAVA_VM_NAME =
		2;
	
	/** Java VM Vendor. */
	public static final short JAVA_VM_VENDOR =
		3;
	
	/** Java VM E-Mail. */
	public static final short JAVA_VM_EMAIL =
		4;
	
	/** Java VM URL. */
	public static final short JAVA_VM_URL =
		5;
	
	/** The guest depth. */
	public static final short GUEST_DEPTH =
		6;
	
	/** Main class. */
	public static final short MAIN_CLASS =
		7;
	
	/** Main program arguments. */
	public static final short MAIN_ARGUMENTS =
		8;
	
	/** Is this a MIDlet? */
	public static final short IS_MIDLET =
		9;
	
	/** Define system propertly. */
	public static final short DEFINE_PROPERTY =
		10;
	
	/** Classpath to use. */
	public static final short CLASS_PATH =
		11;
}

Added runt/libs/summercoat-vm/cc/squirreljme/vm/summercoat/ConfigRomWriter.java.











































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
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
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
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
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.summercoat;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 * These are utility methods to write to config space.
 *
 * @since 2019/06/14
 */
public final class ConfigRomWriter
{
	/**
	 * Not used.
	 *
	 * @since 2019/06/14
	 */
	private ConfigRomWriter()
	{
	}
	
	/**
	 * Writes raw byte data.
	 *
	 * @param __dos The output stream.
	 * @param __opt The option to write.
	 * @param __b The value.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/14
	 */
	public static final void writeData(DataOutputStream __dos, int __opt,
		byte[] __b)
		throws IOException, NullPointerException
	{
		if (__dos == null || __b == null)
			throw new NullPointerException("NARG");
		
		// {@squirreljme.error AE0e Attempt to write very large configuration
		// item. (The length)}
		int len = __b.length;
		if (len >= 65536)
			throw new IOException("AE0e " + len);
		
		// Key, value, and the data
		__dos.writeShort(__opt);
		__dos.writeShort(len);
		__dos.write(__b, 0, len);
	}
	
	/**
	 * Writes key/value.
	 *
	 * @param __dos The output stream.
	 * @param __opt The option to write.
	 * @param __k The key.
	 * @param __v The value.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/14
	 */
	public static final void writeKeyValue(DataOutputStream __dos, int __opt,
		String __k, String __v)
		throws IOException, NullPointerException
	{
		if (__dos == null || __k == null || __v == null)
			throw new NullPointerException("NARG");
		
		// Write data area
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream xdos = new DataOutputStream(baos))
		{
			xdos.writeUTF(__k);
			xdos.writeUTF(__v);
			
			// Write in
			ConfigRomWriter.writeData(__dos, __opt, baos.toByteArray());
		}
	}
	
	/**
	 * Writes the specified integer.
	 *
	 * @param __dos The output stream.
	 * @param __opt The option to write.
	 * @param __v The value to write.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/14
	 */
	public static final void writeInteger(DataOutputStream __dos, int __opt,
		int __v)
		throws IOException, NullPointerException
	{
		if (__dos == null)
			throw new NullPointerException("NARG");
		
		// Write data area
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream xdos = new DataOutputStream(baos))
		{
			xdos.writeInt(__v);
			
			// Write in
			ConfigRomWriter.writeData(__dos, __opt, baos.toByteArray());
		}
	}
	
	/**
	 * Writes the specified string.
	 *
	 * @param __dos The output stream.
	 * @param __opt The option to write.
	 * @param __v The string to write.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/14
	 */
	public static final void writeString(DataOutputStream __dos, int __opt,
		String __v)
		throws IOException, NullPointerException
	{
		if (__dos == null || __v == null)
			throw new NullPointerException("NARG");
		
		// Write data area
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream xdos = new DataOutputStream(baos))
		{
			xdos.writeUTF(__v);
			
			// Write in
			ConfigRomWriter.writeData(__dos, __opt, baos.toByteArray());
		}
	}
	
	/**
	 * Writes the specified strings.
	 *
	 * @param __dos The output stream.
	 * @param __opt The option to write.
	 * @param __v The strings to write.
	 * @throws IOException On write errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/14
	 */
	public static final void writeStrings(DataOutputStream __dos, int __opt,
		String... __v)
		throws IOException, NullPointerException
	{
		if (__dos == null || __v == null)
			throw new NullPointerException("NARG");
		
		// Write data area
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream xdos = new DataOutputStream(baos))
		{
			// Write string length
			int n = __v.length;
			xdos.writeShort(n);
			
			// Write actual strings
			for (int i = 0; i < n; i++)
				xdos.writeUTF(__v[i]);
			
			// Write in
			ConfigRomWriter.writeData(__dos, __opt, baos.toByteArray());
		}
	}
}

Changes to runt/libs/summercoat-vm/cc/squirreljme/vm/summercoat/StaticAllocator.java.

10
11
12
13
14
15
16

17
18
19
20
21
22
23
package cc.squirreljme.vm.summercoat;

/**
 * This class is used to assist in static allocation of data.
 *
 * @since 2019/04/24
 */

public final class StaticAllocator
{
	/** Start address. */
	protected final int base;
	
	/** The current size. */
	private int _size;







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package cc.squirreljme.vm.summercoat;

/**
 * This class is used to assist in static allocation of data.
 *
 * @since 2019/04/24
 */
@Deprecated
public final class StaticAllocator
{
	/** Start address. */
	protected final int base;
	
	/** The current size. */
	private int _size;

Changes to runt/libs/summercoat-vm/cc/squirreljme/vm/summercoat/SummerCoatFactory.java.

6
7
8
9
10
11
12

13
14
15
16
17
18
19
..
26
27
28
29
30
31
32

33
34
35
36
37
38
39
...
162
163
164
165
166
167
168

























































169
170
171
172
173
174
175
...
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
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
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
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
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
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
...
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.summercoat;


import cc.squirreljme.jvm.Constants;
import dev.shadowtail.classfile.mini.MinimizedClassFile;
import dev.shadowtail.classfile.mini.MinimizedField;
import dev.shadowtail.classfile.mini.MinimizedMethod;
import dev.shadowtail.classfile.mini.MinimizedPool;
import dev.shadowtail.classfile.nncc.NativeCode;
import dev.shadowtail.jarfile.MinimizedJarHeader;
................................................................................
import cc.squirreljme.vm.VMSuiteManager;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;

import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import net.multiphasicapps.io.HexDumpOutputStream;
import net.multiphasicapps.profiler.ProfilerSnapshot;
................................................................................
		int ramsize = DefaultConfiguration.DEFAULT_RAM_SIZE,
			ramstart = RAM_START_ADDRESS;
		vmem.mapRegion(new RawMemory(ramstart, ramsize));
		
		// Initialize configuration memory
		WritableMemory cmem = new RawMemory(CONFIG_BASE_ADDR, CONFIG_SIZE);
		vmem.mapRegion(cmem);

























































		
		// Read the boot JAR offset of this packfile
		int bootjaroff = rombase + vmem.memReadInt(rombase +
				MinimizedPackHeader.OFFSET_OF_BOOTJAROFFSET),
			bootjarsize = vmem.memReadInt(rombase +
				MinimizedPackHeader.OFFSET_OF_BOOTJARSIZE);
		
................................................................................
			throw new RuntimeException("AE06", e);
		}
		
		// Load the bootstrap JAR header
		int bra = bootjaroff + bjh.bootoffset,
			lram;
		
		// Allocate and initialize configuration data
		StaticAllocator confalloc = new StaticAllocator(CONFIG_BASE_ADDR);
		int xxclasspth = this.__memStrings(bjh, ramstart, vmem, confalloc,
				SummerCoatFactory.classPathToStringArray(__cp)),
			xxsysprops = this.__memStrings(bjh, ramstart, vmem, confalloc,
				SummerCoatFactory.stringMapToStrings(__sprops)),
			xxmainclss = this.__memString(bjh, ramstart, vmem, confalloc,
				__maincl),
			xxmainargs = this.__memStrings(bjh, ramstart, vmem, confalloc,
				__args);
		
		// Load the boot RAM
		try (DataInputStream dis = new DataInputStream(
			new ReadableMemoryInputStream(vmem, bra, bjh.bootsize)))
		{
			// Read entire RAM space
			lram = dis.readInt();
			byte[] bram = new byte[lram];
................................................................................
			ramstart + bjh.bootpool;
		iframe._registers[NativeCode.STATIC_FIELD_REGISTER] =
			ramstart + bjh.bootsfieldbase;
		
		// Execute the CPU to boot the machine
		cpu.run();
		
		if (true)
			throw new todo.TODO();
		
		throw new todo.TODO();
		/*
		// Size of RAM
		int ramsize = DefaultConfiguration.DEFAULT_RAM_SIZE,
			sfspace = DefaultConfiguration.DEFAULT_STATIC_FIELD_SIZE;
		
		// Initialize and map virtual memory
		VirtualMemory vmem = new VirtualMemory();
		vmem.mapRegion(sm);
		vmem.mapRegion(new RawMemory(RAM_START_ADDRESS, ramsize));
		
		// Initialize the suite space and load the boot address
		sm.__init();
		int kernaddr = sm._bootjaroff,
			bootaddr = -1;
		
		// Static memory allocation
		StaticAllocator statalloc = new StaticAllocator(RAM_START_ADDRESS);
		
		// Write raw strings into memory which describe the various VM
		// arguments and such. This mostly refers to the class to start once
		// the VM has initialized itself
		int xxclasspth = this.__memStrings(vmem, statalloc,
				SummerCoatFactory.classPathToStringArray(__cp)),
			xxsysprops = this.__memStrings(vmem, statalloc,
				SummerCoatFactory.stringMapToStrings(__sprops)),
			xxmainclss = this.__memString(vmem, statalloc, __maincl),
			xxmainargs = this.__memStrings(vmem, statalloc, __args);
		
		// The base address of the kernel object
		int kobjbase;
		
		// Read the information on the boot class into memory, we need to
		// initialize and setup a bunch of fields for it
		int spoolbase;
		try (InputStream kin = new ReadableMemoryInputStream(vmem,
			kernaddr, 1048576))
		{
			// Decode the class file so we can perform some primitive
			// pre-initialization of the kernel. This is needed because the
			// bootstrap needs access to fields and other methods in the
			// bootstrap class.
			MinimizedClassFile minikern = MinimizedClassFile.decode(kin);
			
			// Allocate the kernel object
			kobjbase = statalloc.allocate(Kernel.OBJECT_BASE_SIZE +
				minikern.header.ifbytes);
			
			// Write fixed class ID into object base and an initial reference
			// count of 1
			vmem.memWriteInt(kobjbase + Kernel.OBJECT_CLASS_OFFSET,
				FixedClassIDs.KERNEL);
			vmem.memWriteInt(kobjbase + Kernel.OBJECT_COUNT_OFFSET,
				1);
			
			// The base address of the static pool along with its size
			int poolcount = minikern.header.poolcount,
				spoolsize = poolcount * 4;
			spoolbase = statalloc.allocate(spoolsize);
			
			// Offset to the code area in this minimized method
			int scodebase = kernaddr + minikern.header.smoff,
				icodebase = kernaddr + minikern.header.imoff;
			
			// Initialize the static pool
			MinimizedPool pool = minikern.pool;
			for (int i = 1; i < poolcount; i++)
			{
				// The resulting converted value
				int cv;
				
				// Handle the type and value
				Object pv = pool.get(i);
				switch (pool.type(i))
				{
						// Just map strings to null
					case STRING:
						cv = 0;
						break;
						
						// Read of another field, will be the field offset
					case ACCESSED_FIELD:
						AccessedField af = (AccessedField)pv;
						
						// The kernel class
						if (af.field().className().equals(minikern.thisName()))
							if (af.type().isStatic())
								cv = Kernel.OBJECT_BASE_SIZE + minikern.field(
									true, af.field().memberNameAndType()).
									offset;
							else
								cv = Kernel.OBJECT_BASE_SIZE + minikern.field(
									false, af.field().memberNameAndType()).
									offset;
						
						// Some other class
						else
							cv = _BAD_POOL_VALUE;
						break;
						
						// Try to map a class index to a pre-existing ID
					case CLASS_NAME:
						cv = FixedClassIDs.of(pv.toString());
						if (cv < 0)
							cv = _BAD_POOL_VALUE;
						break;
						
						// The pointer to the run-time pool for the given
						// class
					case CLASS_POOL:
						if (((ClassPool)pv).name.toString().equals(
							"cc/squirreljme/runtime/cldc/vki/Kernel"))
							cv = spoolbase;
						else
							cv = _BAD_POOL_VALUE;
						break;
						
						// Invoked method
					case INVOKED_METHOD:
						InvokedMethod iv = (InvokedMethod)pv;
						
						// The kernel class
						if (iv.handle().outerClass().equals(
							minikern.thisName()))
							if (iv.type().isStatic())
								cv = scodebase + minikern.method(true, iv.
									handle().nameAndType()).codeoffset;
							else
								cv = icodebase + minikern.method(false, iv.
									handle().nameAndType()).codeoffset;
						
						// Some other class
						else
							cv = _BAD_POOL_VALUE;
						break;
						
						// Integer
					case INTEGER:
						cv = (Integer)pv;
						break;
						
						// Float
					case FLOAT:
						cv = Float.floatToRawIntBits((Float)pv);
						break;
						
						// Long
					case LONG:
						throw new todo.TODO();
						
						// Double
					case DOUBLE:
						throw new todo.TODO();
						
						// Where is this information
					case WHERE_IS_THIS:
						{
							// Get method index part
							int id = pool.part(i, 0);
							
							// Instance method? And get the index
							boolean isinstance = ((id &
								WhereIsThis.INSTANCE_BIT) != 0);
							int mdx = (id & (~WhereIsThis.INSTANCE_BIT));
							
							// Set this to the where offset
							cv = (isinstance ? icodebase : scodebase) +
								minikern.methods(!isinstance)[mdx].whereoffset;
						}
						break;
						
						// These are just informational, ignore for now
					case METHOD_DESCRIPTOR:
					case CLASS_NAMES:
						cv = _BAD_POOL_VALUE;
						break;
						
					default:
						throw new todo.OOPS(pool.type(i).name());
				}
				
				// Store into pool area
				int sld;
				vmem.memWriteInt((sld = spoolbase + (4 * i)), cv);
			}
			
			// Find pointers to methods within the kernel
			for (MinimizedMethod mm : minikern.methods(false))
			{
				// Where this method is located
				int codeoff = (mm.flags().isStatic() ? scodebase : icodebase) +
					mm.codeoffset;
				
				// Depends on the name
				switch (mm.name.toString())
				{
						// The starting point of the kernel (boot)
					case "__start":
						bootaddr = codeoff;
						break;
					
						// Ignore
					default:
						continue;
				}
			}
			
			// Go through instance fields and set their data fields
			for (MinimizedField mf : minikern.fields(false))
			{
				// Memory field offer
				int kfo = kobjbase + Kernel.OBJECT_BASE_SIZE + mf.offset;
				
				// Value depends on the field
				switch (mf.name.toString())
				{
						// ROM address
					case "romaddr":
						vmem.memWriteInt(kfo, SUITE_BASE_ADDR);
						break;
						
						// Kernel class definition (miniform)
					case "kernaddr":
						vmem.memWriteInt(kfo, kernaddr);
						
						// Kernel object base
					case "kobjbase":
						vmem.memWriteInt(kfo, kobjbase);
						break;
						
						// Static memory size
					case "staticmemsize":
						vmem.memWriteInt(kfo, statalloc.size());
						break;
						
						// Starting memory address
					case "memaddr":
						vmem.memWriteInt(kfo, RAM_START_ADDRESS);
						break;
					
						// Size of memory
					case "memsize":
						vmem.memWriteInt(kfo, ramsize);
						break;
						
						// Is this a MIDlet?
					case "ismidlet":
						vmem.memWriteInt(kfo, (__ismid ? 1 : 0));
						break;
						
						// The guest depth
					case "guestdepth":
						vmem.memWriteInt(kfo, __gd);
						break;
						
						// The classpath
					case "classpath":
						vmem.memWriteInt(kfo, xxclasspth);
						break;
						
						// System properties
					case "sysprops":
						vmem.memWriteInt(kfo, xxsysprops);
						break;
						
						// Main class
					case "mainclass":
						vmem.memWriteInt(kfo, xxmainclss);
						break;
						
						// Main arguments
					case "mainargs":
						vmem.memWriteInt(kfo, xxmainargs);
						break;
						
						// Static field space
					case "sfspace":
						vmem.memWriteInt(kfo, sfspace);
						break;
					
						// Ignore
					default:
						continue;
				}
			}
		}
		
		// {@squirreljme.error AE0y Could not read the kernel class for
		// initialization}.
		catch (IOException e)
		{
			throw new RuntimeException("AE0y", e);
		}
		
		// Setup virtual CPU to execute
		NativeCPU cpu = new NativeCPU(vmem);
		NativeCPU.Frame iframe = cpu.enterFrame(bootaddr, kobjbase);
		
		// Seed initial frame registers
		iframe._registers[NativeCode.POOL_REGISTER] = spoolbase;
		
		// Execute the CPU to boot the machine
		cpu.run();
		
		if (true)
			throw new todo.TODO();
		
		// Setup root machine which has our base suite manager
		RootMachine rm = new RootMachine(__sm, __ps, __gd);
		
		// Need to map to cached VMs
		CachingSuiteManager suites = rm.suites;
		int n = __cp.length;
		CachingClassLibrary[] libs = new CachingClassLibrary[n];
		for (int i = 0; i < n; i++)
			libs[i] = suites.loadLibrary(__cp[i]);
		
		// Now create the starting main task
		return new ExitAwaiter(rm.statuses, rm.createTask(libs, __maincl,
			__ismid, __sprops, __args).status, __ps);
		*/
	}
	
	/**
	 * This writes a string to memory somewhere.
	 *
	 * @param __mjh Minimized JAR header.
	 * @param __rams RAM start address.
	 * @param __wm Memory that can be written to.
	 * @param __sa Static allocator.
	 * @param __s The string to encode.
	 * @return The address the string was stored at.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/04/21
	 */
	private int __memString(MinimizedJarHeader __mjh, int __rams,
		WritableMemory __wm, StaticAllocator __sa, String __s)
		throws NullPointerException
	{
		if (__wm == null || __sa == null || __s == null)
			throw new NullPointerException("NARG");
		
		// Encode bytes
		byte[] encode;
		try
		{
			encode = __s.getBytes("utf-8");
		}
		catch (UnsupportedEncodingException e)
		{
			encode = __s.getBytes();
		}
		
		// Allocate data
		int rv = __sa.allocate(Constants.ARRAY_BASE_SIZE + encode.length);
		
		// Write class ID, initial refcount, and length
		__wm.memWriteInt(rv + Constants.OBJECT_CLASS_OFFSET,
			__rams + __mjh.bootclassidba);
		__wm.memWriteInt(rv + Constants.OBJECT_COUNT_OFFSET,
			1);
		__wm.memWriteInt(rv + Constants.ARRAY_LENGTH_OFFSET,
			encode.length);
		
		// Write byte data
		int vbase = rv + Constants.ARRAY_BASE_SIZE;
		for (int i = 0, n = encode.length; i < n; i++, vbase++)
			__wm.memWriteByte(vbase, encode[i]);
		
		// Return pointer
		return rv;
	}
	
	/**
	 * Creates an array which is an array of bytes containing all of the
	 * various strings.
	 *
	 * @param __mjh Minimized JAR header.
	 * @param __rams RAM start address.
	 * @param __wm The memory to write to.
	 * @param __sa The allocator used.
	 * @param __ss The strings to convert.
	 * @return The memory address of the {@code byte[][]} array.
	 * @since 2019/04/27
	 */
	private int __memStrings(MinimizedJarHeader __mjh, int __rams,
		WritableMemory __wm, StaticAllocator __sa, String... __ss)
		throws NullPointerException
	{
		if (__sa == null)
			throw new NullPointerException("NARG");
		
		// Force to exist
		if (__ss == null)
			__ss = new String[0];
		
		// The number of elements to store
		int n = __ss.length;
		
		// Allocate data
		int rv = __sa.allocate(Constants.ARRAY_BASE_SIZE + (n * 4));
		
		// Write class ID, initial refcount, and length
		__wm.memWriteInt(rv + Constants.OBJECT_CLASS_OFFSET,
			__rams + __mjh.bootclassidbaa);
		__wm.memWriteInt(rv + Constants.OBJECT_COUNT_OFFSET,
			1);
		__wm.memWriteInt(rv + Constants.ARRAY_LENGTH_OFFSET,
			n);
		
		// Write byte data
		int vbase = rv + Constants.ARRAY_BASE_SIZE;
		for (int i = 0; i < n; i++, vbase += 4)
		{
			String s = __ss[i];
			__wm.memWriteInt(vbase, (s == null ? 0 :
				this.__memString(__mjh, __rams, __wm, __sa, s)));
		}
		
		// Return pointer
		return rv;
	}
	
	/**
	 * Converts a class path to a string array.
	 *
	 * @param __cp The class path to convert.
	 * @return The resulting string array.
................................................................................
			throw new NullPointerException("NARG");
		
		int n = __cp.length;
		String[] rv = new String[n];
		for (int i = 0; i < n; i++)
			rv[i] = __cp[i].name();
		
		return rv;
	}
	
	/**
	 * Converts a string array to a string array.
	 *
	 * @param __s The strings to convert.
	 * @return The resulting string.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/04/21
	 */
	public static final String[] stringMapToStrings(Map<String, String> __s)
		throws NullPointerException
	{
		if (__s == null)
			throw new NullPointerException("NARG");
		
		// Setup
		int n = __s.size() * 2;
		String[] rv = new String[n];
		
		// Map in keys and values
		int i = 0;
		for (Map.Entry<String, String> s : __s.entrySet())
		{
			rv[i++] = s.getKey();
			rv[i++] = s.getValue();
		}
		
		// Done
		return rv;
	}
}








>







 







>







 







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







 







<
<
<
<
<
<
<
<
<
<
<







 







<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







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




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
...
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
...
246
247
248
249
250
251
252











253
254
255
256
257
258
259
...
354
355
356
357
358
359
360

361






































































































































































































































































































































































































































362
363
364
365
366
367
368
...
376
377
378
379
380
381
382






























383
384
385
386
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.summercoat;

import cc.squirreljme.jvm.ConfigRomType;
import cc.squirreljme.jvm.Constants;
import dev.shadowtail.classfile.mini.MinimizedClassFile;
import dev.shadowtail.classfile.mini.MinimizedField;
import dev.shadowtail.classfile.mini.MinimizedMethod;
import dev.shadowtail.classfile.mini.MinimizedPool;
import dev.shadowtail.classfile.nncc.NativeCode;
import dev.shadowtail.jarfile.MinimizedJarHeader;
................................................................................
import cc.squirreljme.vm.VMSuiteManager;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import net.multiphasicapps.io.HexDumpOutputStream;
import net.multiphasicapps.profiler.ProfilerSnapshot;
................................................................................
		int ramsize = DefaultConfiguration.DEFAULT_RAM_SIZE,
			ramstart = RAM_START_ADDRESS;
		vmem.mapRegion(new RawMemory(ramstart, ramsize));
		
		// Initialize configuration memory
		WritableMemory cmem = new RawMemory(CONFIG_BASE_ADDR, CONFIG_SIZE);
		vmem.mapRegion(cmem);
		
		// Write configuration information
		try (DataOutputStream dos = new DataOutputStream(
			new WritableMemoryOutputStream(cmem, 0, CONFIG_SIZE)))
		{
			// Version
			ConfigRomWriter.writeString(dos, ConfigRomType.JAVA_VM_VERSION,
				"0.3.0");
			
			// Name
			ConfigRomWriter.writeString(dos, ConfigRomType.JAVA_VM_NAME,
				"SquirrelJME SummerCoat");
			
			// Vendor
			ConfigRomWriter.writeString(dos, ConfigRomType.JAVA_VM_VENDOR,
				"Stephanie Gawroriski");
			
			// E-Mail
			ConfigRomWriter.writeString(dos, ConfigRomType.JAVA_VM_EMAIL,
				"xerthesquirrel@gmail.com");
			
			// URL
			ConfigRomWriter.writeString(dos, ConfigRomType.JAVA_VM_URL,
				"https://squirreljme.cc/");
			
			// Guest depth
			ConfigRomWriter.writeInteger(dos, ConfigRomType.GUEST_DEPTH,
				__gd);
			
			// Main class
			if (__maincl != null)
				ConfigRomWriter.writeString(dos, ConfigRomType.MAIN_CLASS,
					__maincl);
			
			// Is midlet?
			ConfigRomWriter.writeInteger(dos, ConfigRomType.IS_MIDLET,
				(__ismid ? 1 : 0));
			
			// System properties
			if (__sprops != null)
				for (Map.Entry<String, String> e : __sprops.entrySet())
				{
					ConfigRomWriter.writeKeyValue(dos,
						ConfigRomType.DEFINE_PROPERTY,
						e.getKey(), e.getValue());
				}
			
			// Class path
			ConfigRomWriter.writeStrings(dos, ConfigRomType.CLASS_PATH,
				SummerCoatFactory.classPathToStringArray(__cp));
		}
		
		// {@squirreljme.error AE0d Could not write to configuration ROM.}
		catch (IOException e)
		{
			throw new VMException("AE0d", e);
		}
		
		// Read the boot JAR offset of this packfile
		int bootjaroff = rombase + vmem.memReadInt(rombase +
				MinimizedPackHeader.OFFSET_OF_BOOTJAROFFSET),
			bootjarsize = vmem.memReadInt(rombase +
				MinimizedPackHeader.OFFSET_OF_BOOTJARSIZE);
		
................................................................................
			throw new RuntimeException("AE06", e);
		}
		
		// Load the bootstrap JAR header
		int bra = bootjaroff + bjh.bootoffset,
			lram;
		











		// Load the boot RAM
		try (DataInputStream dis = new DataInputStream(
			new ReadableMemoryInputStream(vmem, bra, bjh.bootsize)))
		{
			// Read entire RAM space
			lram = dis.readInt();
			byte[] bram = new byte[lram];
................................................................................
			ramstart + bjh.bootpool;
		iframe._registers[NativeCode.STATIC_FIELD_REGISTER] =
			ramstart + bjh.bootsfieldbase;
		
		// Execute the CPU to boot the machine
		cpu.run();
		

		throw new todo.TODO();






































































































































































































































































































































































































































	}
	
	/**
	 * Converts a class path to a string array.
	 *
	 * @param __cp The class path to convert.
	 * @return The resulting string array.
................................................................................
			throw new NullPointerException("NARG");
		
		int n = __cp.length;
		String[] rv = new String[n];
		for (int i = 0; i < n; i++)
			rv[i] = __cp[i].name();
		






























		return rv;
	}
}