Check-in [a738e4fa50]

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

Overview
Comment:Un-deprecate API_LEVEL but instead have it be used to detect if the execution engine is too old.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip-springcoat-bringup
Files: files | file ages | folders
SHA1: a738e4fa5067d8a5ba5589beaeecae09c6f2c471
User & Date: stephanie.gawroriski 2020-05-10 20:04:01
Context
2020-05-10
20:14
Add note about execution level update. check-in: a8b7dfa961 user: stephanie.gawroriski tags: wip-springcoat-bringup
20:04
Un-deprecate API_LEVEL but instead have it be used to detect if the execution engine is too old. check-in: a738e4fa50 user: stephanie.gawroriski tags: wip-springcoat-bringup
19:11
Undo the additional branch. check-in: 5859c5acc4 user: stephanie.gawroriski tags: wip-springcoat-bringup
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
		if (__m == null)
			throw new NullPointerException("NARG");
		
		if (__args == null)
			__args = new Object[0];
		
		// Debug
		todo.DEBUG.note("enterFrame(%s::%s, %s)", __m.inClass(),
			__m.nameAndType(), Arrays.<Object>asList(__args));
		
		// {@squirreljme.error BK1k Cannot enter the frame for a method which
		// is abstract. (The class the method is in; The method name and type)}
		if (__m.isAbstract())
			throw new SpringVirtualMachineException(String.format("BK1k %s %s",
				__m.inClass(), __m.nameAndType()));
		







|
|







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
		if (__m == null)
			throw new NullPointerException("NARG");
		
		if (__args == null)
			__args = new Object[0];
		
		// Debug
		/*todo.DEBUG.note("enterFrame(%s::%s, %s)", __m.inClass(),
			__m.nameAndType(), Arrays.<Object>asList(__args));*/
		
		// {@squirreljme.error BK1k Cannot enter the frame for a method which
		// is abstract. (The class the method is in; The method name and type)}
		if (__m.isAbstract())
			throw new SpringVirtualMachineException(String.format("BK1k %s %s",
				__m.inClass(), __m.nameAndType()));
		

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

6
7
8
9
10
11
12

13
14
15
16
17
18
19
...
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
...
288
289
290
291
292
293
294





















295
296
297
298
299
300
301
// 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.SystemCallException;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodName;
................................................................................
			// they have simple functions.
			switch (__sid)
			{
				case SystemCallIndex.QUERY_INDEX:
					switch (__a)
					{
							// Supported system calls

						case SystemCallIndex.ERROR_GET:
						case SystemCallIndex.ERROR_SET:
						case SystemCallIndex.EXIT:
						case SystemCallIndex.FRAME_TASK_ID_GET:
						case SystemCallIndex.HW_THREAD:

						case SystemCallIndex.QUERY_INDEX:
							return 1;
						
							// Not supported
						default:
							return 0;
					}
					




					// Get error
				case SystemCallIndex.ERROR_GET:
					return __thread.thread._syscallerrors[(__a < 0 ||
						__a >= SystemCallIndex.NUM_SYSCALLS ? 0 : __a)];
				
					// Set error
				case SystemCallIndex.ERROR_SET:
................................................................................
				case SystemCallIndex.FRAME_TASK_ID_GET:
					return __thread.thread.taskId();
					
					// Hardware thread access
				case SystemCallIndex.HW_THREAD:
					return __thread.machine.tasks.hardwareThreads.sysCall(
						__thread, __a, __b, __c, __d, __e, __f, __g, __h);





















				
					// 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);
					







>







 







>





>








>
>
>
>







 







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







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
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
...
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
// 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.Constants;
import cc.squirreljme.jvm.SystemCallError;
import cc.squirreljme.jvm.SystemCallException;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodName;
................................................................................
			// they have simple functions.
			switch (__sid)
			{
				case SystemCallIndex.QUERY_INDEX:
					switch (__a)
					{
							// Supported system calls
						case SystemCallIndex.API_LEVEL:
						case SystemCallIndex.ERROR_GET:
						case SystemCallIndex.ERROR_SET:
						case SystemCallIndex.EXIT:
						case SystemCallIndex.FRAME_TASK_ID_GET:
						case SystemCallIndex.HW_THREAD:
						case SystemCallIndex.PD_OF_STDERR:
						case SystemCallIndex.QUERY_INDEX:
							return 1;
						
							// Not supported
						default:
							return 0;
					}
					
					// Current API level
				case SystemCallIndex.API_LEVEL:
					return Constants.API_LEVEL_2020_05_10;
					
					// Get error
				case SystemCallIndex.ERROR_GET:
					return __thread.thread._syscallerrors[(__a < 0 ||
						__a >= SystemCallIndex.NUM_SYSCALLS ? 0 : __a)];
				
					// Set error
				case SystemCallIndex.ERROR_SET:
................................................................................
				case SystemCallIndex.FRAME_TASK_ID_GET:
					return __thread.thread.taskId();
					
					// Hardware thread access
				case SystemCallIndex.HW_THREAD:
					return __thread.machine.tasks.hardwareThreads.sysCall(
						__thread, __a, __b, __c, __d, __e, __f, __g, __h);
					
					// Pipe descriptor of standard output
				case SystemCallIndex.PD_OF_STDOUT:
					return 1;
					
					// Pipe descriptor of standard error
				case SystemCallIndex.PD_OF_STDERR:
					return 2;
					
					// Write byte to standard descriptor
				case SystemCallIndex.PD_WRITE_BYTE:
					switch (__a)
					{
						case 1: System.out.print((char)__b); break;
						case 2: System.err.print((char)__b); break;
						
						default:
							error = SystemCallError.PIPE_DESCRIPTOR_INVALID;
							return 0;
					}
					return 1;
				
					// 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);
					

Changes to modules/cldc-compact/src/main/java/cc/squirreljme/jvm/Constants.java.

98
99
100
101
102
103
104
105



106

	/** Do not exit on TO-DO? */
	byte DEBUG_NO_TODO_EXIT =
		0b0000_0100;
	
	/** The thread ID for out-of-bound IPC events. */
	int OOB_IPC_THREAD =
		0xFFFFFFFF;
}












|
>
>
>
|
>
98
99
100
101
102
103
104
105
106
107
108
109
110
	/** Do not exit on TO-DO? */
	byte DEBUG_NO_TODO_EXIT =
		0b0000_0100;
	
	/** The thread ID for out-of-bound IPC events. */
	int OOB_IPC_THREAD =
		0xFFFFFFFF;
	
	/** This is the API level that is used for "new" SquirrelJME versions. */
	int API_LEVEL_2020_05_10 =
		4_0_20131;
}

Changes to modules/cldc-compact/src/main/java/cc/squirreljme/jvm/SystemCallIndex.java.

5
6
7
8
9
10
11


12
13
14
15
16
17
18
...
147
148
149
150
151
152
153
154


155
156
157
158
159
160
161
162
163
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm;



/**
 * This contains the index of system calls.
 *
 * @see SystemCall
 * @since 2019/05/23
 */
public interface SystemCallIndex
................................................................................
		11;
	
	/**
	 * The API Level of the VM, this has been deprecated since the current
	 * SquirrelJME API specified in these system calls better handles various
	 * features.
	 *
	 * @squirreljme.syscallreturn The API level of the virtual machine.


	 */
	@Deprecated
	byte API_LEVEL =
		12;
	
	/**
	 * The pipe descriptor for stdin.
	 *
	 * @squirreljme.syscallreturn The pipe descriptor for standard input.







>
>







 







|
>
>

<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm;

import cc.squirreljme.runtime.cldc.lang.ApiLevel;

/**
 * This contains the index of system calls.
 *
 * @see SystemCall
 * @since 2019/05/23
 */
public interface SystemCallIndex
................................................................................
		11;
	
	/**
	 * The API Level of the VM, this has been deprecated since the current
	 * SquirrelJME API specified in these system calls better handles various
	 * features.
	 *
	 * @squirreljme.syscallreturn The API level of the virtual machine, for
	 * older VMs this will be one of the {@link ApiLevel} values, for all
	 * new and current VMs this will be {@link Constants#API_LEVEL_2020_05_10}.
	 */

	byte API_LEVEL =
		12;
	
	/**
	 * The pipe descriptor for stdin.
	 *
	 * @squirreljme.syscallreturn The pipe descriptor for standard input.

Changes to modules/cldc-compact/src/main/java/cc/squirreljme/jvm/boot/SystemBoot.java.

5
6
7
8
9
10
11


12

13
14
15
16
17
18
19
..
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
..
75
76
77
78
79
80
81
82































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

package cc.squirreljme.jvm.boot;



import cc.squirreljme.jvm.SystemCall;

import cc.squirreljme.jvm.VirtualProcess;
import cc.squirreljme.jvm.memory.ReadableAssemblyMemory;

/**
 * Boots the SquirrelJME virtual machine system.
 *
 * @since 2020/03/26
................................................................................
	@SuppressWarnings("StaticVariableUsedBeforeInitialization")
	public static ConfigReader config()
	{
		return SystemBoot._config;
	}
	
	/**
	 * System boot entry point.
	 *
	 * @param __ramAddr The RAM address.
	 * @param __ramLen The size of RAM.
	 * @param __configAddr The configuration address.
	 * @param __configLen The configuration length.

	 * @since 2020/03/26
	 */
	@SuppressWarnings({"unused"})
	static void __sysBoot(long __ramAddr, int __ramLen,
		long __configAddr, int __configLen)
	{
		// Initialize the links in RAM
		Allocator.__initRamLinks(__ramAddr, __ramLen);






		
		// Setup the configuration reader to obtain our entry point info
		ConfigReader config = new ConfigReader(
			new ReadableAssemblyMemory(__configAddr, __configLen));























































		SystemBoot._config = config;
		
		// Spawn our primary process and initialize it
		VirtualProcess primary = VirtualProcess.spawn();
		
		// Start the process
		primary.start();
		
................................................................................
			{
				// Ignore ...
			}
		
		// Now exit with the code
		SystemCall.exit(exitCode);
	}
}






































>
>

>







 







|

|
|
|
|
>
|

<
|
|

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







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
...
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
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.boot;

import cc.squirreljme.jvm.Assembly;
import cc.squirreljme.jvm.Constants;
import cc.squirreljme.jvm.SystemCall;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.jvm.VirtualProcess;
import cc.squirreljme.jvm.memory.ReadableAssemblyMemory;

/**
 * Boots the SquirrelJME virtual machine system.
 *
 * @since 2020/03/26
................................................................................
	@SuppressWarnings("StaticVariableUsedBeforeInitialization")
	public static ConfigReader config()
	{
		return SystemBoot._config;
	}
	
	/**
	 * Prints a bunch of characters to the output.
	 *
	 * @param __pd The pipe to write to.
	 * @param __a Character A.
	 * @param __b Character B.
	 * @param __c Character C.
	 * @param __d Character D.
	 * @since 2020/05/10
	 */

	private static void __ancientPrint(int __pd, char __a, char __b, char __c,
		char __d)
	{
		Assembly.sysCallP(SystemCallIndex.PD_WRITE_BYTE, __pd,
			(__a >= 0x7F ? '?' : __a));
		Assembly.sysCallP(SystemCallIndex.PD_WRITE_BYTE, __pd,
			(__b >= 0x7F ? '?' : __b));
		Assembly.sysCallP(SystemCallIndex.PD_WRITE_BYTE, __pd,
			(__c >= 0x7F ? '?' : __c));
		Assembly.sysCallP(SystemCallIndex.PD_WRITE_BYTE, __pd,
			(__d >= 0x7F ? '?' : __d));
	}



	
	/**
	 * This is used when the version of SquirrelJME is too ancient.
	 *
	 * This method assumes that no memory system has been initialized.
	 *
	 * @since 2020/05/10
	 */
	private static void __ancientSquirrelJME()
	{
		// We need to get stderr's output so we can print a message saying
		// that this version is too old and is broken
		int stdErr = Assembly.sysCallPV(SystemCallIndex.PD_OF_STDERR);
		
		// This may seem complicated to print, however when this code runs
		// the allocator cannot actually initialize because the given addresses
		// are not valid...
		// "This version of SquirrelJME requires a newer execution engine..."
		SystemBoot.__ancientPrint(stdErr, 'T', 'h', 'i', 's');
		SystemBoot.__ancientPrint(stdErr, ' ', 'v', 'e', 'r');
		SystemBoot.__ancientPrint(stdErr, 's', 'i', 'o', 'n');
		SystemBoot.__ancientPrint(stdErr, ' ', 'o', 'f', ' ');
		SystemBoot.__ancientPrint(stdErr, 'S', 'q', 'u', 'i');
		SystemBoot.__ancientPrint(stdErr, 'r', 'r', 'e', 'l');
		SystemBoot.__ancientPrint(stdErr, 'J', 'M', 'E', ' ');
		SystemBoot.__ancientPrint(stdErr, 'r', 'e', 'q', 'u');
		SystemBoot.__ancientPrint(stdErr, 'i', 'r', 'e', 's');
		SystemBoot.__ancientPrint(stdErr, ' ', 'a', ' ', 'n');
		SystemBoot.__ancientPrint(stdErr, 'e', 'w', 'e', 'r');
		SystemBoot.__ancientPrint(stdErr, ' ', 'e', 'x', 'e');
		SystemBoot.__ancientPrint(stdErr, 'c', 'u', 't', 'i');
		SystemBoot.__ancientPrint(stdErr, 'o', 'n', ' ', 'e');
		SystemBoot.__ancientPrint(stdErr, 'n', 'g', 'i', 'n');
		SystemBoot.__ancientPrint(stdErr, 'e', '.', '.', '.');
		
		// End line sequence, just assume Windows endings here
		SystemBoot.__ancientPrint(stdErr, '\r', '\n',
			'\r', '\n');
		
		// Try to stop the VM somehow
		Assembly.breakpoint();
		Assembly.sysCallPV(SystemCallIndex.EXIT, -13);
	}
	
	/**
	 * Performs the actual boot process.
	 *
	 * @param __ramAddr The RAM Address.
	 * @param __ramLen The length of RAM.
	 * @param __config The configuration data.
	 * @since 2020/05/10
	 */
	static void __boot(long __ramAddr, int __ramLen, ConfigReader __config)
	{
		// Store configuration for later
		SystemBoot._config = __config;
		
		// Spawn our primary process and initialize it
		VirtualProcess primary = VirtualProcess.spawn();
		
		// Start the process
		primary.start();
		
................................................................................
			{
				// Ignore ...
			}
		
		// Now exit with the code
		SystemCall.exit(exitCode);
	}
	
	/**
	 * System boot entry point.
	 *
	 * @param __ramAddr The RAM address.
	 * @param __ramLen The size of RAM.
	 * @param __configAddr The configuration address.
	 * @param __configLen The configuration length.
	 * @since 2020/03/26
	 */
	@SuppressWarnings({"unused"})
	static void __sysBoot(long __ramAddr, int __ramLen,
		long __configAddr, int __configLen)
	{
		if (Assembly.sysCallPV(SystemCallIndex.API_LEVEL) <
			Constants.API_LEVEL_2020_05_10)
		{
			SystemBoot.__ancientSquirrelJME();
			return;
		}
		
		// Initialize the links in RAM
		Allocator.__initRamLinks(__ramAddr, __ramLen);
		
		// Setup the configuration reader to obtain our entry point info
		ConfigReader config = new ConfigReader(
			new ReadableAssemblyMemory(__configAddr, __configLen));
		
		// Forward to standard boot process
		SystemBoot.__boot(__ramAddr, __ramLen, config);
	}
}