Check-in [84e7eb88f5]

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

Overview
Comment:Add a bunch of classes that were not committed.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip-springcoat-bringup
Files: files | file ages | folders
SHA1: 84e7eb88f520614a5a021b1dd6d9f8465e8091a9
User & Date: stephanie.gawroriski 2020-03-21 23:06:57
Context
2020-03-21
23:18
Move exceptions to their own package. check-in: 180c07b0a3 user: stephanie.gawroriski tags: wip-springcoat-bringup
23:06
Add a bunch of classes that were not committed. check-in: 84e7eb88f5 user: stephanie.gawroriski tags: wip-springcoat-bringup
19:10
Partial work on updating SpringCoat to launch using the new means. check-in: d8283e0e04 user: stephanie.gawroriski tags: wip-springcoat-bringup
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MachineMetrics.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
// -*- 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.springcoat;

/**
 * Standard metrics which define how SpringCoat operates.
 *
 * @since 2020/03/14
 */
public final class MachineMetrics
{
	/**
	 * Not used.
	 *
	 * @since 2020/03/14
	 */
	private MachineMetrics()
	{
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/ObjectLoader.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
// -*- 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.springcoat;

import cc.squirreljme.runtime.cldc.debug.Debugging;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValueString;
import net.multiphasicapps.classfile.MethodNameAndType;

/**
 * This is the loader for various different object types.
 *
 * @since 2020/03/14
 */
public final class ObjectLoader
{
	/** The string class. */
	private static final ClassName _STRING_CLASS =
		new ClassName("java/lang/String");
	
	/** Load-UTF and intern function. */
	private static final MethodNameAndType _LOAD_NAME_AND_TYPE =
		new MethodNameAndType("__loadUtfAndIntern",
		"(J)Ljava/lang/String;");
	
	/**
	 * Not used.
	 *
	 * @since 2020/03/14
	 */
	private ObjectLoader()
	{
	}
	
	/**
	 * Loads the class info from the given class.
	 *
	 * @param __class The class ot map.
	 * @return The object for this class.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/03/21
	 */
	public static SpringObject loadClassInfo(SpringThreadWorker __thread,
		SpringClass __class)
		throws NullPointerException
	{
		if (__thread == null || __class == null)
			throw new NullPointerException("NARG");
		
		throw Debugging.todo();
	}
	
	/**
	 * Loads a constant pool based string value into the intern pool of the
	 * VM.
	 *
	 * @param __thread The creating thread.
	 * @param __in The input string.
	 * @return The resulting object.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/03/14
	 */
	public static Object loadConstantValueString(SpringThreadWorker __thread,
		ConstantValueString __in)
		throws NullPointerException
	{
		if (__thread == null || __in == null)
			throw new NullPointerException("NARG");
		
		// Load the UTF string into memory
		SpringMachine machine = __thread.machine;
		SpringPointer utfPointer = machine.tasks.memory.loadUtf(
			__in.toString());
		
		// Call the string internal intern since it does the things needed
		return __thread.invokeMethod(true, ObjectLoader._STRING_CLASS,
			ObjectLoader._LOAD_NAME_AND_TYPE, utfPointer.pointer);
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/ReferenceChainer.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
// -*- 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.springcoat;

/**
 * This class manages the reference chain.
 *
 * @since 2020/03/13
 */
public final class ReferenceChainer
{
	/** The pointer value. */
	private SpringPointer _pointer;
	
	/**
	 * Gets the chain.
	 *
	 * @return The chain pointer.
	 * @since 2020/03/13
	 */
	public final SpringPointer get()
	{
		return this._pointer;
	}
	
	/**
	 * Sets the chain.
	 *
	 * @param __v The new value to set.
	 * @since 2020/03/13
	 */
	public final void set(SpringPointer __v)
	{
		this._pointer = __v;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/ReferenceCounter.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
// -*- 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.springcoat;

/**
 * This is used to wrap the reference counter.
 *
 * @since 2020/03/13
 */
public final class ReferenceCounter
{
	/**
	 * The current count.
	 *
	 * @deprecated This will be transitioned to somewhere in memory.
	 */
	@Deprecated
	private int _count =
		1;
	
	/**
	 * Increases the count and returns the new value.
	 *
	 * @return The new value.
	 * @since 2020/03/13
	 */
	public final int up()
	{
		return ++this._count;
	}
}

Deleted emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringInstance.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <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.springcoat;

/**
 * This represents an instance of an object which has a class and defined
 * fields.
 *
 * @since 2018/07/22
 */
public final class SpringInstance
{
}

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












































Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringMachine.java.

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
..
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
...
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
...
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
...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
...
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
...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.ThreadStartIndex;
import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.runtime.cldc.lang.GuestDepth;
import cc.squirreljme.runtime.swm.EntryPoint;
import cc.squirreljme.runtime.swm.EntryPoints;
import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.emulator.vm.VMResourceAccess;
import cc.squirreljme.emulator.vm.VMSuiteManager;
import cc.squirreljme.emulator.vm.VirtualMachine;
import java.io.IOException;
import java.io.InputStream;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValueString;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodNameAndType;
import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import net.multiphasicapps.classfile.PrimitiveType;
import net.multiphasicapps.tool.manifest.JavaManifest;

/**
 * This class contains the instance of the SpringCoat virtual machine and has
 * a classpath along with all the needed storage for variables and such.
 *
 * @since 2018/07/29
 */
................................................................................
		new ArrayList<>();
	
	/** Static fields which exist within the virtual machine. */
	@Deprecated
	private final Map<SpringField, SpringFieldStorage> _staticfields =
		new HashMap<>();
	
	/** Global strings representing singular constants. */
	@Deprecated
	private final Map<ConstantValueString, SpringObject> _strings =
		new HashMap<>();
	
	/** Class objects which represent a given class. */
	@Deprecated
	private final Map<ClassName, SpringObject> _classobjects =
		new HashMap<>();
	
	/** Class names by their objects. */
	@Deprecated
	private final Map<SpringObject, ClassName> _namesbyclass =
		new HashMap<>();
	
	/** Main entry point arguments. */
	private final String[] _args;
	
	/** Long to string map. */
	@Deprecated
	private final Map<Long, String> _strlongtostring =
		new HashMap<>();
	
	/** String to long map. */
	@Deprecated
	private final Map<String, Long> _strstringtolong =
		new HashMap<>();
	
	/** System properties. */
	final Map<String, String> _sysproperties;
	
	/** The next thread ID to use. */
	private volatile int _nextthreadid;
	
	/** The next long to choose. */
	private long _strnextlong;
	
	/** Is the VM exiting? */
	private volatile boolean _exiting;
	
	/** Exit code of the VM. */
	volatile int _exitcode;
	
	/**
................................................................................
			
			// Store thread
			threads.add(rv);
			return rv;
		}
	}
	
	/**
	 * Resolves the given string pointer.
	 *
	 * @param __p The pointer.
	 * @return The string at the given pointer or {@code null} if it has no
	 * resolution.
	 * @since 2018/09/29
	 */
	@Deprecated
	public final String debugResolveString(long __p)
	{
		if (__p == -1L)
			return null;
		
		synchronized (this.strlock)
		{
			return this._strlongtostring.get(__p);
		}
	}
	
	/**
	 * Unresolves the given string.
	 *
	 * @param __s The string to unresolve.
	 * @return The pointer to the string.
	 * @since 2018/09/29
	 */
	@Deprecated
	public final long debugUnresolveString(String __s)
	{
		if (__s == null)
			return -1L;
		
		synchronized (this.strlock)
		{
			Long rv = this._strstringtolong.get(__s);
			if (rv != null)
				return rv;
			
			Long next = ++this._strnextlong;
			this._strstringtolong.put(__s, next);
			this._strlongtostring.put(next, __s);
			
			return next;
		}
	}
	
	/**
	 * Exits the virtual machine.
	 *
	 * @param __code The exit code.
	 * @throws SpringMachineExitException To signal virtual machine exit.
	 * @since 2018/10/13
	 */
................................................................................
			if (rv == null)
				throw new SpringVirtualMachineException("BK19");
			
			return rv;
		}
	}
	
	/**
	 * Returns the number of threads which are currently alive and active.
	 *
	 * @return The number of active and alive threads.
	 * @since 2018/09/03
	 */
	public final int numThreads()
	{
		// Store thread
		List<SpringThread> threads = this._threads;
		synchronized (threads)
		{
			return threads.size();
		}
	}
	
	/**
	 * Returns the access for resources.
	 *
	 * @return The resource access.
	 * @since 2018/10/07
	 */
	public final VMResourceAccess resourceAccess()
	{
		return this.resourceaccessor;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/13
	 */
	@Override
	public final void run()
	{
................................................................................
		
		// Initialize thread index values
		SpringArrayObjectLong tsiArgs =
			(SpringArrayObjectLong)worker.allocateArray(
			worker.resolveClass(PrimitiveType.LONG.toClassName()),
			ThreadStartIndex.NUM_INDEXES);
		tsiArgs.set(ThreadStartIndex.MAIN_CLASS_INFO,
			worker.mapClassToClassInfo(entrycl).pointerArea().basePointer());
		tsiArgs.set(ThreadStartIndex.MAIN_ARGUMENTS,
			outargs.pointerArea().basePointer());
		
		// Enter the frame for that method using the arguments we passed (in
		// a static fashion)
		mainthread.enterFrame(worker.loadClass(
			new ClassName("java/lang/__ThreadStarter__")).lookupMethod(
			true, new MethodNameAndType("__start", "([J)V")),
			tsiArgs.pointerArea().basePointer());
		
		// The main although it executes in this context will always have the
		// same exact logic as other threads running apart from this main
		// thread, so no code is needed to be duplicated at all.
		worker.run();
		
		// Wait until all threads have terminated before actually leaving
................................................................................
	 * @since 2018/10/26
	 */
	public final VMSuiteManager suiteManager()
	{
		return this.suites;
	}
	
	/**
	 * Returns the task manager which is used.
	 *
	 * @return The task manager.
	 * @since 2018/11/04
	 */
	public final SpringTaskManager taskManager()
	{
		return this.tasks;
	}
	
	/**
	 * Splits long to integers.
	 *
	 * @param __dx The index.
	 * @param __v The output integers.
	 * @param __l The input long.
	 * @since 2018/09/29
	 */
	public static final void longToInt(int __dx, int[] __v, long __l)
	{
		__v[__dx] = (int)(__l >>> 32);
		__v[__dx + 1] = (int)__l;
	}
	
	/**
	 * Returns the mapping of class names to {@link Class} instances.
	 *
	 * @return The mapping of class names to object instances.
	 * @since 2018/09/19
	 */
	final Map<ClassName, SpringObject> __classObjectMap()
................................................................................
	 * @return The static field map.
	 * @since 2018/09/08
	 */
	final Map<SpringField, SpringFieldStorage> __staticFieldMap()
	{
		return this._staticfields;
	}
	
	/**
	 * Returns the global string map.
	 *
	 * @return The global string map.
	 * @since 2018/09/16
	 */
	final Map<ConstantValueString, SpringObject> __stringMap()
	{
		return this._strings;
	}
}








<
<
<
<
<
|



|
|
>






<
<

<

<







 







<
<
<
<
<













<
<
<
<
<
<
<
<
<
<






<
<
<







 







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







 







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







 







|

|






|







 







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







 







|
<
<
|
<
<
<
<
<
<
<
<
<
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
..
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
...
168
169
170
171
172
173
174















































175
176
177
178
179
180
181
...
265
266
267
268
269
270
271



























272
273
274
275
276
277
278
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
...
429
430
431
432
433
434
435

























436
437
438
439
440
441
442
...
461
462
463
464
465
466
467
468


469









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

package cc.squirreljme.vm.springcoat;






import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import cc.squirreljme.emulator.vm.VMResourceAccess;
import cc.squirreljme.emulator.vm.VMSuiteManager;
import cc.squirreljme.emulator.vm.VirtualMachine;
import cc.squirreljme.jvm.ThreadStartIndex;
import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.vm.VMClassLibrary;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.multiphasicapps.classfile.ClassName;


import net.multiphasicapps.classfile.MethodNameAndType;

import net.multiphasicapps.classfile.PrimitiveType;


/**
 * This class contains the instance of the SpringCoat virtual machine and has
 * a classpath along with all the needed storage for variables and such.
 *
 * @since 2018/07/29
 */
................................................................................
		new ArrayList<>();
	
	/** Static fields which exist within the virtual machine. */
	@Deprecated
	private final Map<SpringField, SpringFieldStorage> _staticfields =
		new HashMap<>();
	





	/** Class objects which represent a given class. */
	@Deprecated
	private final Map<ClassName, SpringObject> _classobjects =
		new HashMap<>();
	
	/** Class names by their objects. */
	@Deprecated
	private final Map<SpringObject, ClassName> _namesbyclass =
		new HashMap<>();
	
	/** Main entry point arguments. */
	private final String[] _args;
	










	/** System properties. */
	final Map<String, String> _sysproperties;
	
	/** The next thread ID to use. */
	private volatile int _nextthreadid;
	



	/** Is the VM exiting? */
	private volatile boolean _exiting;
	
	/** Exit code of the VM. */
	volatile int _exitcode;
	
	/**
................................................................................
			
			// Store thread
			threads.add(rv);
			return rv;
		}
	}
	















































	/**
	 * Exits the virtual machine.
	 *
	 * @param __code The exit code.
	 * @throws SpringMachineExitException To signal virtual machine exit.
	 * @since 2018/10/13
	 */
................................................................................
			if (rv == null)
				throw new SpringVirtualMachineException("BK19");
			
			return rv;
		}
	}
	



























	/**
	 * {@inheritDoc}
	 * @since 2018/09/13
	 */
	@Override
	public final void run()
	{
................................................................................
		
		// Initialize thread index values
		SpringArrayObjectLong tsiArgs =
			(SpringArrayObjectLong)worker.allocateArray(
			worker.resolveClass(PrimitiveType.LONG.toClassName()),
			ThreadStartIndex.NUM_INDEXES);
		tsiArgs.set(ThreadStartIndex.MAIN_CLASS_INFO,
			ObjectLoader.loadClassInfo(worker, entrycl).pointerArea().base());
		tsiArgs.set(ThreadStartIndex.MAIN_ARGUMENTS,
			outargs.pointerArea().base());
		
		// Enter the frame for that method using the arguments we passed (in
		// a static fashion)
		mainthread.enterFrame(worker.loadClass(
			new ClassName("java/lang/__ThreadStarter__")).lookupMethod(
			true, new MethodNameAndType("__start", "([J)V")),
			tsiArgs.pointerArea().base());
		
		// The main although it executes in this context will always have the
		// same exact logic as other threads running apart from this main
		// thread, so no code is needed to be duplicated at all.
		worker.run();
		
		// Wait until all threads have terminated before actually leaving
................................................................................
	 * @since 2018/10/26
	 */
	public final VMSuiteManager suiteManager()
	{
		return this.suites;
	}
	

























	/**
	 * Returns the mapping of class names to {@link Class} instances.
	 *
	 * @return The mapping of class names to object instances.
	 * @since 2018/09/19
	 */
	final Map<ClassName, SpringObject> __classObjectMap()
................................................................................
	 * @return The static field map.
	 * @since 2018/09/08
	 */
	final Map<SpringField, SpringFieldStorage> __staticFieldMap()
	{
		return this._staticfields;
	}
}












Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringPointer.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
// -*- 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.springcoat;

/**
 * This represents a single pointer within SpringCoat.
 *
 * @since 2020/03/11
 */
public final class SpringPointer
	implements Comparable<SpringPointer>
{
	/** The pointer value. */
	public final long pointer;
	
	/** Pointer as integer value. */
	public int pointerInt;
	
	/**
	 * Initializes the pointer.
	 *
	 * @param __a The address of the pointer.
	 * @since 2020/03/13
	 */
	public SpringPointer(long __a)
	{
		if (__a < 0 || __a > Integer.MAX_VALUE)
			throw new IllegalArgumentException(String.format(
				"Illegal pointer: %08x", __a));
		
		this.pointer = __a;
		this.pointerInt = (int)__a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/11
	 */
	@Override
	public final int compareTo(SpringPointer o)
	{
		throw new todo.TODO();
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/11
	 */
	@Override
	public final int hashCode()
	{
		return this.pointerInt;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/11
	 */
	@Override
	public final boolean equals(Object __o)
	{
		if (__o == this)
			return true;
		
		if (!(__o instanceof SpringPointer))
			return false;
		
		return this.pointerInt == ((SpringPointer)__o).pointerInt;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/21
	 */
	@Override
	public final String toString()
	{
		throw new todo.TODO();
	}
}

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringPointerArea.java.

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	
	/**
	 * Returns the base pointer.
	 *
	 * @return The base pointer.
	 * @since 2020/03/13
	 */
	public final SpringPointer basePointer()
	{
		return new SpringPointer(this.base);
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21







|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	
	/**
	 * Returns the base pointer.
	 *
	 * @return The base pointer.
	 * @since 2020/03/13
	 */
	public final SpringPointer base()
	{
		return new SpringPointer(this.base);
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringThreadWorker.java.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
....
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
....
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
....
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.runtime.cldc.debug.Debugging;
import java.io.PrintStream;
import java.util.Map;
import net.multiphasicapps.classfile.ByteCode;
import net.multiphasicapps.classfile.ClassFlags;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValue;
import net.multiphasicapps.classfile.ConstantValueClass;
................................................................................
			}
		}
		
		// Return the input class
		return __cl;
	}
	
	/**
	 * Maps a class to class info.
	 *
	 * @param __class The class ot map.
	 * @return The object for this class.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/03/21
	 */
	public SpringObject mapClassToClassInfo(SpringClass __class)
		throws NullPointerException
	{
		if (__class == null)
			throw new NullPointerException("NARG");
		
		throw Debugging.todo();
	}
	
	/**
	 * Handles a native action within the VM.
	 *
	 * Note that the return value should be a native type, it is translated
	 * as needed.
	 *
	 * @param __class The class name.
................................................................................
				return this.mapValueToObject(this.mapValueToObject(__args[0])
					.refChainer().get());
				
				// Set the reference chain of an object
			case "refChainSet":
				this.mapValueToObject(__args[0]).refChainer().set(
					this.mapValueToObject(__args[1]).pointerArea()
					.basePointer());
				return null;
				
				// Reference count up
			case "refCountUp":
				this.mapValueToObject(__args[0]).refCounter().up();
				return null;
				
................................................................................
		// Null reference?
		if (__p == 0)
			return SpringNullObject.NULL;
		
		return this.machine.pointers.findObject(__p);
	}
	
	/**
	 * Returns the string of the given ID.
	 *
	 * @param __id The ID to get.
	 * @return The resulting string.
	 * @since 2019/06/16
	 */
	@Deprecated
	public final String uniqueString(int __id)
	{
		if (__id == 0)
			return null;
		return this.machine.debugResolveString((int)__id);
	}
	
	/**
	 * Returns a unique ID for the given string.
	 *
	 * @param __s The String to get the ID of.
	 * @return The unique string ID.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/16
	 */
	@Deprecated
	public final int uniqueStringId(String __s)
		throws NullPointerException
	{
		if (__s == null)
			return 0;
		
		return (int)this.machine.debugUnresolveString(__s);
	}
	
	/**
	 * Performs a special invoke.
	 *
	 * @param __i The instruction.
	 * @param __t The current thread.
	 * @param __f The current frame.
	 * @throws NullPointerException On null arguments.







<







 







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







 







|







 







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







6
7
8
9
10
11
12

13
14
15
16
17
18
19
....
1050
1051
1052
1053
1054
1055
1056

















1057
1058
1059
1060
1061
1062
1063
....
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
....
3488
3489
3490
3491
3492
3493
3494

































3495
3496
3497
3498
3499
3500
3501
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;


import java.io.PrintStream;
import java.util.Map;
import net.multiphasicapps.classfile.ByteCode;
import net.multiphasicapps.classfile.ClassFlags;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValue;
import net.multiphasicapps.classfile.ConstantValueClass;
................................................................................
			}
		}
		
		// Return the input class
		return __cl;
	}
	

















	/**
	 * Handles a native action within the VM.
	 *
	 * Note that the return value should be a native type, it is translated
	 * as needed.
	 *
	 * @param __class The class name.
................................................................................
				return this.mapValueToObject(this.mapValueToObject(__args[0])
					.refChainer().get());
				
				// Set the reference chain of an object
			case "refChainSet":
				this.mapValueToObject(__args[0]).refChainer().set(
					this.mapValueToObject(__args[1]).pointerArea()
					.base());
				return null;
				
				// Reference count up
			case "refCountUp":
				this.mapValueToObject(__args[0]).refCounter().up();
				return null;
				
................................................................................
		// Null reference?
		if (__p == 0)
			return SpringNullObject.NULL;
		
		return this.machine.pointers.findObject(__p);
	}
	

































	/**
	 * Performs a special invoke.
	 *
	 * @param __i The instruction.
	 * @param __t The current thread.
	 * @param __f The current frame.
	 * @throws NullPointerException On null arguments.

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SystemCallHandler.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
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
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
// -*- 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.springcoat;

import cc.squirreljme.emulator.AbstractSystemCallHandler;
import cc.squirreljme.jvm.SystemCallError;
import cc.squirreljme.jvm.SystemCallIndex;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodName;
import net.multiphasicapps.classfile.MethodNameAndType;
import net.multiphasicapps.classfile.PrimitiveType;

/**
 * This handles system calls within SpringCoat.
 *
 * @since 2020/03/13
 */
public final class SystemCallHandler
	extends AbstractSystemCallHandler
{
	/** The class for JVM function (un-pure handler). */
	private static final ClassName _JVM_FUNCTION_CLASS =
		new ClassName("cc/squirreljme/jvm/JVMFunction");
	
	/** name and type for unpure calls. */
	private static final MethodNameAndType _UNPURE_NAME_AND_TYPE =
		new MethodNameAndType("jvmSystemCall", "(SIIIIIIII)J");
	
	/**
	 * Dispatches the system call accordingly to either the un-pure handler
	 * within the VM or the pure handler.
	 *
	 * @param __thread The calling thread.
	 * @param __name The name of the method.
	 * @param __type The type of the method.
	 * @param __args The arguments for the call.
	 * @return The return value of the system call
	 * @since 2020/03/13
	 */
	public static Object dispatch(SpringThreadWorker __thread,
		MethodName __name, MethodDescriptor __type, Object... __args)
		throws NullPointerException
	{
		if (__thread == null || __name == null || __type == null)
			throw new NullPointerException("NARG");
		
		// Basic system call parameters
		short sysCallId = ((Number)__args[0]).shortValue();
		boolean isPure = (__name.toString().indexOf('P') >= 0);
		
		// Dispatch the call
		long rv;
		switch (__args.length - 1)
		{
			case 0:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					0,
					0,
					0,
					0,
					0,
					0,
					0,
					0);
				break;
				
			case 1:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					0,
					0,
					0,
					0,
					0,
					0,
					0);
				break;
				
			case 2:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					((Number)__args[2]).intValue(),
					0,
					0,
					0,
					0,
					0,
					0);
				break;
				
			case 3:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					((Number)__args[2]).intValue(),
					((Number)__args[3]).intValue(),
					0,
					0,
					0,
					0,
					0);
				break;
				
			case 4:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					((Number)__args[2]).intValue(),
					((Number)__args[3]).intValue(),
					((Number)__args[4]).intValue(),
					0,
					0,
					0,
					0);
				break;
				
			case 5:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					((Number)__args[2]).intValue(),
					((Number)__args[3]).intValue(),
					((Number)__args[4]).intValue(),
					((Number)__args[5]).intValue(),
					0,
					0,
					0);
				break;
				
			case 6:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					((Number)__args[2]).intValue(),
					((Number)__args[3]).intValue(),
					((Number)__args[4]).intValue(),
					((Number)__args[5]).intValue(),
					((Number)__args[6]).intValue(),
					0,
					0);
				break;
				
			case 7:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					((Number)__args[2]).intValue(),
					((Number)__args[3]).intValue(),
					((Number)__args[4]).intValue(),
					((Number)__args[5]).intValue(),
					((Number)__args[6]).intValue(),
					((Number)__args[7]).intValue(),
					0);
				break;
				
			case 8:
				rv = SystemCallHandler.dispatch(__thread, isPure, sysCallId,
					((Number)__args[1]).intValue(),
					((Number)__args[2]).intValue(),
					((Number)__args[3]).intValue(),
					((Number)__args[4]).intValue(),
					((Number)__args[5]).intValue(),
					((Number)__args[6]).intValue(),
					((Number)__args[7]).intValue(),
					((Number)__args[8]).intValue());
				break;
			
			default:
				throw new SpringVirtualMachineException(
					"Invalid system call parameter count: " + __args.length);
		}
		
		// The return value type depends on our signature
		if (!__type.hasReturnValue())
			return null;
		else if (__type.returnValue().primitiveType() == PrimitiveType.INTEGER)
			return (int)rv;
		return rv;
	}
	
	/**
	 * Dispatches the system call accordingly to either the un-pure handler
	 * within the VM or the pure handler.
	 *
	 * @param __thread The calling thread.
	 * @param __pure Is this a pure system call?
	 * @param __sid The system call index.
	 * @param __a A.
	 * @param __b B.
	 * @param __c C.
	 * @param __d D.
	 * @param __e E.
	 * @param __f F.
	 * @param __g G.
	 * @param __h H.
	 * @return The result of the system call.
	 * @since 2020/03/14
	 */
	public static long dispatch(SpringThreadWorker __thread, boolean __pure,
		short __sid, int __a, int __b, int __c, int __d, int __e, int __f,
		int __g, int __h)
	{
		// Non-pure system calls are sent to the code within the JVM itself,
		// this way they can be patched or otherwise supported without needing
		// to be an actual part of the VM.
		if (!__pure)
			return ((Number)__thread.invokeMethod(true,
			SystemCallHandler._JVM_FUNCTION_CLASS,
			SystemCallHandler._UNPURE_NAME_AND_TYPE,
			__a, __b, __c, __d, __e, __f, __g, __h)).longValue();
		
		// Use internal handler for system calls.
		return SystemCallHandler.handle(__thread, __sid,
			__a, __b, __c, __d,__e, __f, __g, __h);
	}
	
	/**
	 * Handles the system call logic.
	 *
	 * @param __thread The calling thread.
	 * @param __sid The system call index.
	 * @param __a A.
	 * @param __b B.
	 * @param __c C.
	 * @param __d D.
	 * @param __e E.
	 * @param __f F.
	 * @param __g G.
	 * @param __h H.
	 * @return The result of the system call.
	 * @since 2020/03/14
	 */
	private static long handle(SpringThreadWorker __thread, short __sid,
		int __a, int __b, int __c, int __d, int __e, int __f, int __g, int __h)
	{
		// We must always record the error state at the end of execution
		int error = SystemCallError.NO_ERROR;
		try
		{
			// Different system calls have different logic, but generally
			// they have simple functions.
			switch (__sid)
			{
				case SystemCallIndex.QUERY_INDEX:
					switch (__a)
					{
							// Supported system calls
						case SystemCallIndex.QUERY_INDEX:
							return 1;
						
							// Not supported
						default:
							return 0;
					}
				
					// System call not supported
				default:
					System.err.printf("Un-handled sysCall#%d(%d, %d, %d, " +
						"%d, %d, %d, %d, %d)%n",
						__sid, __a, __b, __c, __d, __e, __f, __g, __h);
					
					error = SystemCallError.UNSUPPORTED_SYSTEM_CALL;
					return 0;
			}
		}
		
		// Store the error state
		finally
		{
			__thread.thread._syscallerrors[
				(__sid < 0 || __sid >= SystemCallIndex.NUM_SYSCALLS ?
				0 : __sid)] = error;
		}
	}
	
	/* *
	 * Internal system call handling.
	 *
	 * @param __si System call index.
	 * @param __args Arguments.
	 * @return The result.
	 * @since 2019/05/23
	 * /
	public final long systemCall(short __si, int... __args)
	{
		// Make at least 8!
		if (__args == null)
			__args = new int[8];
		if (__args.length < 8)
			__args = Arrays.copyOf(__args, 8);
		
		// Error state for the last call of this type
		int[] errors = this.thread._syscallerrors;
		
		// Return value with error value, to set if any
		long rv;
		int err;
		
		// Depends on the system call type
		switch (__si)
		{
				// Check if system call is supported
			case SystemCallIndex.QUERY_INDEX:
				{
					err = 0;
					switch (__args[0])
					{
						case SystemCallIndex.API_LEVEL:
						case SystemCallIndex.CALL_STACK_HEIGHT:
						case SystemCallIndex.CALL_STACK_ITEM:
						case SystemCallIndex.ERROR_GET:
						case SystemCallIndex.ERROR_SET:
						case SystemCallIndex.EXIT:
						case SystemCallIndex.FATAL_TODO:
						case SystemCallIndex.GARBAGE_COLLECT:
						case SystemCallIndex.LOAD_STRING:
						case SystemCallIndex.PD_OF_STDERR:
						case SystemCallIndex.PD_OF_STDIN:
						case SystemCallIndex.PD_OF_STDOUT:
						case SystemCallIndex.PD_WRITE_BYTE:
						case SystemCallIndex.SLEEP:
						case SystemCallIndex.TIME_MILLI_WALL:
						case SystemCallIndex.TIME_NANO_MONO:
						case SystemCallIndex.VMI_MEM_FREE:
						case SystemCallIndex.VMI_MEM_MAX:
						case SystemCallIndex.VMI_MEM_USED:
							rv = 1;
							break;
						
						default:
							rv = 0;
							break;
					}
				}
				break;
				
				// Returns the height of the call stack
			case SystemCallIndex.CALL_STACK_HEIGHT:
				{
					rv = this.thread.frames().length;
					err = 0;
				}
				break;
				
				// Returns the given call stack item
			case SystemCallIndex.CALL_STACK_ITEM:
				{
					// Need to get all the stack frames first
					SpringThread.Frame[] frames = this.thread.frames();
					int numframes = frames.length;
					int curf = (numframes - __args[0]) - 1;
					
					// Out of range item
					if (curf < 0 || curf >= numframes)
					{
						rv = -1;
						err = SystemCallError.VALUE_OUT_OF_RANGE;
					}
					
					// Depends on the item
					else
					{
						// Reset
						rv = err = 0;
						
						// Get method we are in
						SpringMethod inmethod = frames[curf].method();
						
						// Depends on the item
						switch (__args[1])
						{
								// Class name
							case CallStackItem.CLASS_NAME:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(
										inmethod.inClass().toString());
								break;

								// The method name.
							case CallStackItem.METHOD_NAME:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(inmethod.
										nameAndType().name().toString());
								break;

								// The method type.
							case CallStackItem.METHOD_TYPE:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(inmethod.
										nameAndType().type().toString());
								break;

								// The current file.
							case CallStackItem.SOURCE_FILE:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(
										inmethod.inFile());
								break;

								// Source line.
							case CallStackItem.SOURCE_LINE:
								rv = frames[curf].lastExecutedPcSourceLine();
								break;

								// The PC address.
							case CallStackItem.PC_ADDRESS:
							case CallStackItem.JAVA_PC_ADDRESS:
								rv = frames[curf].lastExecutedPc();
								break;

							default:
								err = SystemCallError.VALUE_OUT_OF_RANGE;
								break;
						}
					}
				}
				break;
				
				// Get error
			case SystemCallIndex.ERROR_GET:
				{
					// If the ID is valid then a bad array access will be used
					int dx = __args[0];
					if (dx < 0 || dx >= SystemCallIndex.NUM_SYSCALLS)
						dx = SystemCallIndex.QUERY_INDEX;
					
					// Return the stored error code
					synchronized (errors)
					{
						rv = errors[dx];
					}
					
					// Always succeeds
					err = 0;
				}
				break;
				
				// Set error
			case SystemCallIndex.ERROR_SET:
				{
					// If the ID is valid then a bad array access will be used
					int dx = __args[0];
					if (dx < 0 || dx >= SystemCallIndex.NUM_SYSCALLS)
						dx = SystemCallIndex.QUERY_INDEX;
					
					// Return last error code, and set new one
					synchronized (errors)
					{
						rv = errors[dx];
						errors[dx] = __args[0];
					}
					
					// Always succeeds
					err = 0;
				}
				break;
				
				// Exit the VM
			case SystemCallIndex.EXIT:
				{
					// Tell everything to cleanup and exit
					this.thread.profiler.exitAll(System.nanoTime());
					this.machine.exit((Integer)__args[0]);
					
					rv = 0;
					err = 0;
				}
				break;
				
				// Fatal ToDo
			case SystemCallIndex.FATAL_TODO:
				// {@squirreljme.error BK33 Virtual machine code executed
				// a fatal Todo. (The To Do code)}
				rv = err = 0;
				throw new SpringVirtualMachineException("BK33 " + __args[1]);
				
				// Invoke the garbage collector
			case SystemCallIndex.GARBAGE_COLLECT:
				{
					Runtime.getRuntime().gc();
					
					rv = 0;
					err = 0;
				}
				break;
				
				// Loads a string
			case SystemCallIndex.LOAD_STRING:
				{
					rv = (__args[0] == 0 ? 0 :
						this.uniqueObjectToPointer((SpringObject)
						this.asVMObject(new ConstantValueString(
						this.uniqueString(__args[0])))));
					err = 0;
				}
				break;
			
				// Current wall clock milliseconds (low).
			case SystemCallIndex.TIME_MILLI_WALL:
				{
					rv = System.currentTimeMillis();
					err = 0;
				}
				break;

				// Current monotonic clock nanoseconds (low).
			case SystemCallIndex.TIME_NANO_MONO:
				{
					rv = System.nanoTime();
					err = 0;
				}
				break;
			
				// VM information: Memory free bytes
			case SystemCallIndex.VMI_MEM_FREE:
				{
					rv = (int)Math.min(Integer.MAX_VALUE,
						Runtime.getRuntime().freeMemory());
					err = 0;
				}
				break;
			
				// VM information: Memory used bytes
			case SystemCallIndex.VMI_MEM_USED:
				{
					rv = (int)Math.min(Integer.MAX_VALUE,
						Runtime.getRuntime().totalMemory());
					err = 0;
				}
				break;
			
				// VM information: Memory max bytes
			case SystemCallIndex.VMI_MEM_MAX:
				{
					rv = (int)Math.min(Integer.MAX_VALUE,
						Runtime.getRuntime().maxMemory());
					err = 0;
				}
				break;
				
				// API level
			case SystemCallIndex.API_LEVEL:
				{
					rv = ApiLevel.LEVEL_SQUIRRELJME_0_3_0_DEV;
					err = 0;
				}
				break;
				
				// Pipe descriptor of standard input
			case SystemCallIndex.PD_OF_STDIN:
				{
					rv = 0;
					err = 0;
				}
				break;
				
				// Pipe descriptor of standard output
			case SystemCallIndex.PD_OF_STDOUT:
				{
					rv = 1;
					err = 0;
				}
				break;
				
				// Pipe descriptor of standard error
			case SystemCallIndex.PD_OF_STDERR:
				{
					rv = 1;
					err = 0;
				}
				break;
				
				// Write single byte to PD
			case SystemCallIndex.PD_WRITE_BYTE:
				{
					// Depends on the stream
					int pd = __args[0];
					OutputStream os = (pd == 1 ? System.out :
						(pd == 2 ? System.err : null));
					
					// Write
					if (os != null)
					{
						try
						{
							os.write(__args[1]);
							
							// Okay
							rv = 1;
							err = 0;
						}
						
						// Failed
						catch (IOException e)
						{
							rv = -1;
							err = SystemCallError.PIPE_DESCRIPTOR_BAD_WRITE;
						}
					}
					
					// Failed
					else
					{
						rv = -1;
						err = SystemCallError.PIPE_DESCRIPTOR_INVALID;
					}
				}
				break;
				
				// Sleep
			case SystemCallIndex.SLEEP:
				try
				{
					Thread.sleep(__args[0], __args[1]);
					
					rv = 0;
					err = SystemCallError.NO_ERROR;
				}
				catch (InterruptedException e)
				{
					rv = 1;
					err = SystemCallError.INTERRUPTED;
				}
				break;
			
			default:
				// Returns no value but sets an error
				rv = -1;
				err = SystemCallError.UNSUPPORTED_SYSTEM_CALL;
				
				// If the ID is valid then a bad array access will be used
				if (__si < 0 || __si >= SystemCallIndex.NUM_SYSCALLS)
					__si = SystemCallIndex.QUERY_INDEX;
				break;
		}
		
		// Set error state as needed
		synchronized (errors)
		{
			errors[__si] = err;
		}
		
		// Use returning value
		return rv;
	}*/
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/ThreadStartIndex.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
// -*- 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 a field within the thread starting area which determines
 * parameters and such in a fixed representation.
 *
 * @since 2020/03/21
 */
public interface ThreadStartIndex
{
	/**
	 * Place holder for nothing.
	 *
	 * @since 2002/03/21
	 */
	byte NOTHING =
		0;
	
	/**
	 * The main class to use for the thread entry point.
	 *
	 * @squirreljme.tsiparam 0 The {@link ClassInfo} pointer containing a
	 * reference to the {@code main(String[])} method.
	 * @since 2020/03/21
	 */
	byte MAIN_CLASS_INFO =
		1;
	
	/**
	 * The main arguments to use for the method.
	 *
	 * @squirreljme.tsiparam 0 A {@link String[]} pointer containing the
	 * main arguments to the main method.
	 * @since 2020/03/21
	 */
	byte MAIN_ARGUMENTS =
		2;
	
	/** The number of indexes. */
	byte NUM_INDEXES =
		3;
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/memory/SizeableMemory.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
// -*- 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.memory;

/**
 * This is any memory which can be sized.
 *
 * @since 2020/03/14
 */
public interface SizeableMemory
{
	/** Unknown memory size. */
	int UNKNOWN_SIZE =
		Integer.MIN_VALUE;
	
	/**
	 * Returns the size of this memory region.
	 *
	 * @return The region size or {@link #UNKNOWN_SIZE} if not known/undefined.
	 * @since 2020/03/14
	 */
	int size();
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/runtime/cldc/debug/Debugging.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
// -*- 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.runtime.cldc.debug;

import todo.TODO;

/**
 * This contains static method forwarders.
 *
 * @since 2020/03/21
 */
public final class Debugging
{
	/**
	 * Not used.
	 *
	 * @since 2020/03/21
	 */
	private Debugging()
	{
	}
	
	/**
	 * Emits a To-Do error.
	 *
	 * @param __args Arguments to the error.
	 * @return The generated error.
	 * @since 2020/03/21
	 */
	public static TODO todo(Object... __args)
	{
		return TODO.TODO(__args);
	}
	
	/**
	 * Emits a To-Do note.
	 *
	 * @param __fmt Format string.
	 * @param __args Arguments.
	 * @since 2020/03/31
	 */
	public static void todoNote(String __fmt, Object... __args)
	{
		TODO.note(__fmt, __args);
	}
}

Added modules/cldc-compact/src/main/java/java/lang/__ThreadStarter__.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
// -*- 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 java.lang;

import cc.squirreljme.jvm.Assembly;
import cc.squirreljme.jvm.ThreadStartIndex;
import cc.squirreljme.runtime.cldc.debug.Debugging;

/**
 * This class is responsible for initializing and being the starting point
 * for threads.
 *
 * @since 2020/03/21
 */
@SuppressWarnings("unused")
final class __ThreadStarter__
{
	/**
	 * Not used.
	 *
	 * @since 2020/03/21
	 */
	private __ThreadStarter__()
	{
	}
	
	/**
	 * Starts the given thread.
	 *
	 * @param __tsi Multiple {@link ThreadStartIndex}, which describe how the
	 * thread is to start.
	 * @since 2002/03/21
	 */
	@SuppressWarnings("unused")
	static void __start(long[] __tsi)
	{
		Assembly.breakpoint();
		throw Debugging.todo();
	}
}

Added modules/cldc-compact/src/main/java/todo/CodeProgressError.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
// -*- 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 todo;

/**
 * This is the base class for code progress errors, where there is progress
 * on code that needs to be done somewhere.
 *
 * @since 2020/03/15
 */
public abstract class CodeProgressError
	extends Error
{
	/**
	 * Initializes the exception.
	 *
	 * @param __m The message used.
	 * @since 2020/03/15
	 */
	public CodeProgressError(String __m)
	{
		super(__m);
	}
}

Added modules/cldc-compact/src/main/java/todo/__Utilities__.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
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
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
// -*- 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 todo;

import cc.squirreljme.jvm.Assembly;
import cc.squirreljme.jvm.CallStackItem;
import cc.squirreljme.jvm.Constants;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.runtime.cldc.Poking;
import cc.squirreljme.runtime.cldc.debug.CallTraceElement;

/**
 * Utilities for printing and debugging.
 *
 * @since 2020/03/14
 */
@SuppressWarnings("TodoComment")
final class __Utilities__
{
	/** Used to detect OOPSs/TODOs recursively being called. */
	@SuppressWarnings("StaticVariableMayNotBeInitialized")
	static volatile boolean _DOUBLE_TRIP;
	
	/** Stop formatted text from infinitely printing. */
	@SuppressWarnings("StaticVariableMayNotBeInitialized")
	static volatile boolean _FORMAT_LOCK;
	
	/** Squelch debugging? */
	static final boolean _SQUELCH;
	
	/** The width of the star line. */
	static final int _STAR_LINE_WIDTH =
		52;
	
	/**
	 * Not used.
	 *
	 * @since 2020/03/14
	 */
	private __Utilities__()
	{
	}
	
	static
	{
		// Poke to make sure the required VM stuff is working
		Poking.poke();
		
		int flags = Assembly.sysCallPV(SystemCallIndex.DEBUG_FLAGS);
		
		// Setup flags
		_SQUELCH = ((flags & Constants.DEBUG_SQUELCH_PRINT) != 0);
	}
	
	/**
	 * Prints formatted string.
	 *
	 * @param __a Letter A.
	 * @param __b Letter B.
	 * @param __fmt The format.
	 * @since 2020/03/15
	 */
	@SuppressWarnings("StaticVariableUsedBeforeInitialization")
	public static void dumpFormatLine(char __a, char __b, String __fmt,
		Object... __args)
	{
		// Prevent formatting from printing itself again
		if (__Utilities__._FORMAT_LOCK)
			return;
		__Utilities__._FORMAT_LOCK = true;
		
		// Now print
		try
		{
			// Print prefix
			__Utilities__.printChar(__a);
			__Utilities__.printChar(__b);
			__Utilities__.printChar(' ');
			__Utilities__.printChar('-');
			__Utilities__.printChar('-');
			__Utilities__.printChar(' ');
			
			// End line
			__Utilities__.printChar('\n');
			
			/*
				ps.print(__pfx);
				ps.print(GuestDepth.guestDepth());
				ps.print(' ');
				ps.print(TODO.__formatCondensedTrace(TODO.__where()));
				ps.print(" -- ");
				
				ps.printf(__fmt, __args);
				
				// Add markers to indicate the number of notes which were
				// suppressed
				int suppressed = TODO._supressednotes;
				TODO._supressednotes = 0;
				for (int i = 0; i < suppressed; i++)
					ps.print('^');
				
				ps.println();
			}
			finally
			{
				// In case of exceptions, this will always be unlocked
				TODO._notelock = false;
			}
			 */
		}
		
		// Allow formatted strings to be printed again
		finally
		{
			__Utilities__._FORMAT_LOCK = false;
		}
	}
	
	/**
	 * Dumps the trace to the output using the normal trace logic.
	 *
	 * @param __a Letter A.
	 * @param __a Letter B.
	 * @param __trace The trace to print for.
	 * @since 2020/03/15
	 */
	@SuppressWarnings("StaticVariableUsedBeforeInitialization")
	public static void dumpTrace(char __a, char __b, int[] __trace,
		Object[] __args)
	{
		// Prevent double-tripping of trace handling in the event one is
		// tripped
		if (__Utilities__._DOUBLE_TRIP)
			return;
		__Utilities__._DOUBLE_TRIP = true;
		
		// Dump the trace
		try
		{
			// Starting banner
			__Utilities__.printStarLine(__a, __b);
			
			// Dump the trace
			__Utilities__.printStackTrace(__a, __b, __trace);
			
			// Ending banner
			__Utilities__.printStarLine(__a, __b);
		}
		
		// Reset the tripping state
		finally
		{
			__Utilities__._DOUBLE_TRIP = false;
		}
	}
	
	/**
	 * Prints the given character to the debug output.
	 *
	 * @param __c The output character.
	 * @since 2020/03/15
	 */
	public static void printChar(char __c)
	{
		// Do not print if not requested to
		if (__Utilities__._SQUELCH)
			return;
		
		Assembly.sysCallPV(SystemCallIndex.PD_WRITE_BYTE,
			Assembly.sysCallPV(SystemCallIndex.PD_OF_STDERR, __c));
	}
	
	/**
	 * Prints code to the output.
	 *
	 * @param __a Character A.
	 * @param __b Character B.
	 * @since 2020/03/15
	 */
	public static void printCode(char __a, char __b)
	{
		__Utilities__.printChar(__a);
		__Utilities__.printChar(__b);
		
		__Utilities__.printChar('\n');
	}
	
	/**
	 * Prints a line of asterisks to the output, used for spacing.
	 *
	 * @param __a Letter A.
	 * @param __b Letter B.
	 * @since 2020/03/15
	 */
	public static void printStarLine(char __a, char __b)
	{
		__Utilities__.printChar(__a);
		__Utilities__.printChar(__b);
		__Utilities__.printChar(' ');
		
		for (int i = 0; i < __Utilities__._STAR_LINE_WIDTH; i++)
			__Utilities__.printChar('*');
	}
	
	/**
	 * Prints the current stack trace.
	 *
	 * @param __a Letter A.
	 * @param __b Letter B.
	 * @since 2020/03/15
	 */
	public static void printStackTrace(char __a, char __b)
	{
		__Utilities__.printStackTrace(__a, __b, CallTraceElement.traceRaw());
	}
	
	/**
	 * Prints the current stack trace.
	 *
	 * @param __a Letter A.
	 * @param __b Letter B.
	 * @param __raw The raw stack trace.
	 * @since 2020/03/15
	 */
	public static void printStackTrace(char __a, char __b, int[] __raw)
	{
		// Code signifying the start of a trace
		__Utilities__.printCode(__a, '<');
		
		// Print every stack trace portion
		for (int base = 0, total = __raw.length; base < total;
			base += CallStackItem.NUM_ITEMS)
		{
			// Print starting code
			__Utilities__.printChar(__a);
			__Utilities__.printChar(__b);
			
			// Spacer for organization
			__Utilities__.printChar(' ');
		}
		
		// Code for ending the trace
		__Utilities__.printCode(__a, '>');
		
		/*
		if (__e == null)
			throw new NullPointerException("NARG");
		
		String cn = __e.className(),
			mn = __e.methodName(),
			md = __e.methodDescriptor(),
			fi = __e.file();
		long ad = __e.address();
		int ln = __e.line();
		
		StringBuilder sb = new StringBuilder();
		
		// Location
		if (cn != null)
		{
			// Get identifier part
			int ld = cn.lastIndexOf('.');
			if (ld < 0)
				if ((ld = cn.lastIndexOf('/')) < 0)
					ld = 0;
			
			// Print slimmed down packages since they could be guessed
			for (int i = 0, n = cn.length(); i >= 0 && i < n;)
			{
				// Before the last dot, print single and skip ahead
				if (i < ld)
				{
					sb.append(cn.charAt(i));
					
					int ldi = cn.indexOf('.', i);
					if (ldi < 0)
						ldi = cn.indexOf('/', i);
					
					i = ldi + 1;
				}
				
				// Finish string
				else
				{
					if (i > 0)
						sb.append('.');
					sb.append(cn.substring(i));
					break;
				}
			}
		}
		sb.append("::");
		if (mn != null)
			sb.append(mn);
		
		// Address, if it is valid
		if (ad != -1L)
		{
			sb.append(" @ ");
			sb.append(Long.toString(ad, 16).toUpperCase());
			sb.append("h");
		}
		
		// Add file/line information if it is valid
		if (fi != null)
		{
			sb.append(" (");
			
			// Use blank class name if not specified
			if (cn == null)
				cn = "";
			
			// The class will end with the Java extension
			int ld = cn.lastIndexOf('.');
			if (ld < 0)
				ld = cn.lastIndexOf('/');
			if (ld >= 0)
				cn = cn.substring(ld + 1);
			
			// Determine how many charcters the class name and the file
			// name have in common, so that it can be shortened
			int deep = 0;
			for (int n = Math.min(cn.length(), fi.length()); deep < n; deep++)
				if (cn.charAt(deep) != fi.charAt(deep))
					break;
			
			// Use whole name
			if (deep == 0)
				sb.append(fi);
			
			// Use fragment
			else
			{
				// But only if it does not end in .java, this makes it
				// implied since it is always around
				String sub = fi.substring(deep);
				if (!sub.equals(".java"))
				{
					sb.append('*');
					sb.append(sub);
				}
			}
			
			if (ln >= 0)
			{
				sb.append(':');
				sb.append(ln);
			}
			
			sb.append(')');
		}
		
		return sb.toString();
		
		--------------------- BACKUP METHOD
		
		// Print this and any causes!
		for (Throwable rover = this; rover != null; rover = rover._cause)
		{
			// Supervisor or caused by?
			todo.DEBUG.code('T', (rover == this ? 'S' : 'C'),
				Assembly.objectToPointer(rover));
			
			// The thrown type
			todo.DEBUG.code('T', 'Y', Assembly.memReadInt(
				Assembly.objectToPointer(this),
				Constants.OBJECT_CLASS_OFFSET));
			
			// Obtain the raw trace that was captured on construction
			int[] rawtrace = this._rawtrace;
			int rawn = rawtrace.length;
			
			// Print all the items in it
			for (int base = 0; base < rawn; base += CallStackItem.NUM_ITEMS)
				try
				{
					// Indicate start of element
					todo.DEBUG.code('T', '-');
					
					// Print out the raw details
					todo.DEBUG.codeUtf('T', 'c',
						rawtrace[base + CallStackItem.CLASS_NAME]);
					todo.DEBUG.codeUtf('T', 'n',
						rawtrace[base + CallStackItem.METHOD_NAME]);
					todo.DEBUG.codeUtf('T', 'y',
						rawtrace[base + CallStackItem.METHOD_TYPE]);
					todo.DEBUG.codeUtf('T', '#',
						rawtrace[base + CallStackItem.TASK_ID]);
					todo.DEBUG.codeUtf('T', 'f',
						rawtrace[base + CallStackItem.SOURCE_FILE]);
					todo.DEBUG.code('T', 'l',
						rawtrace[base + CallStackItem.SOURCE_LINE]);
					todo.DEBUG.code('T', 'a',
						rawtrace[base + CallStackItem.PC_ADDRESS]);
					todo.DEBUG.code('T', 'j',
						rawtrace[base + CallStackItem.JAVA_PC_ADDRESS]);
					todo.DEBUG.code('T', 'o',
						rawtrace[base + CallStackItem.JAVA_OPERATION]);
				}
				
				// Error getting stack trace element
				catch (Throwable t)
				{
					todo.DEBUG.code('X', 'T', base);
				}
			
			// Indicate end of current set
			todo.DEBUG.code('T', '<');
		}
		
		// Indicate end of trace log
		todo.DEBUG.code('T', '_');
		 */
	}
}