Check-in [b3686a37ce]

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

Overview
Comment:More test fixes and functionality; Cleanup threads which have been terminated; Hide the terminated variable; Change order of thread initialization, enter main then create the thread instance so we are not quickly terminated this is so that threads are only terminated once.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip-midlevel
Files: files | file ages | folders
SHA1: b3686a37ce8f8361a323ac918c82d1f021ebed73
User & Date: stephanie.gawroriski 2020-06-30 01:28:28
Context
2020-06-30
01:35
Throw the correct exception. check-in: c07a6ae36d user: stephanie.gawroriski tags: wip-midlevel
01:28
More test fixes and functionality; Cleanup threads which have been terminated; Hide the terminated variable; Change order of thread initialization, enter main then create the thread instance so we are not quickly terminated this is so that threads are only terminated once. check-in: b3686a37ce user: stephanie.gawroriski tags: wip-midlevel
2020-06-29
03:25
Do not check bounds in String.charAt(), allow the exception to be thrown; Use System.arraycopy() in ByteArrayInputStream as it can be native; Use full native copies in System.arraycopy() and Arrays.copyOf(); Have a branch specifically for primitive types in System.arraycopy(); Add some pre-checks to optimize away everything else. check-in: 5ae3cf6070 user: stephanie.gawroriski tags: wip-midlevel
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
...
372
373
374
375
376
377
378
































379
380
381
382
383
384
385
...
406
407
408
409
410
411
412










































413
414
415
416
417
418
419
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.ThreadShelf;
import cc.squirreljme.jvm.mle.brackets.VMThreadBracket;
import cc.squirreljme.runtime.cldc.debug.Debugging;
import cc.squirreljme.vm.springcoat.brackets.VMThreadObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodNameAndType;

/**
 * Functions for {@link ThreadShelf}.
................................................................................
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int ms = (int)__args[0];
			int ns = (int)__args[1];
			
			if (ms < 0 || ns < 0)



				Thread.yield();
			else
				try
				{
					Thread.sleep(ms, ns);
				}
				catch (InterruptedException ignored)
................................................................................
				{
					return true;
				}
			
			return false;
		}
	},

















	
	/** {@link ThreadShelf#toVMThread(Thread)}. */
	TO_VM_THREAD("toVMThread:(Ljava/lang/Thread;)Lcc/squirreljme/" +
		"jvm/mle/brackets/VMThreadBracket;")
	{
		/**
		 * {@inheritDoc}
................................................................................
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			VMThreadObject vmThread = (VMThreadObject)__args[0];
			
			// Send an interrupt to the thread
			vmThread.getThread().hardInterrupt();
			
			return null;
		}
	},
................................................................................
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEThread.__vmThread(__args[0]).getThread().isMain();
		}
	},
































	
	/** {@link ThreadShelf#vmThreadStart(VMThreadBracket)}. */
	VM_THREAD_START("vmThreadStart:(Lcc/squirreljme/jvm/mle/brackets/" +
		"VMThreadBracket;)Z")
	{
		/**
		 * {@inheritDoc}
................................................................................
			}
			catch (IllegalThreadStateException ignored)
			{
				return false;
			}
		}
	},










































	
	/* End. */
	;
	
	/** The class which contains the thread starting point. */
	static final ClassName _START_CLASS =
		new ClassName("java/lang/__Start__");







|







 







|
>
>
>







 







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







 







|







 







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







 







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







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
...
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
...
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
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.ThreadShelf;
import cc.squirreljme.jvm.mle.brackets.VMThreadBracket;
import cc.squirreljme.jvm.mle.exceptions.MLECallError;
import cc.squirreljme.vm.springcoat.brackets.VMThreadObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodNameAndType;

/**
 * Functions for {@link ThreadShelf}.
................................................................................
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int ms = (int)__args[0];
			int ns = (int)__args[1];
			
			if (ms < 0 || ns < 0 || ns > 1000000000)
				throw new MLECallError("Out of range time.");
			
			if (ms == 0 && ns == 0)
				Thread.yield();
			else
				try
				{
					Thread.sleep(ms, ns);
				}
				catch (InterruptedException ignored)
................................................................................
				{
					return true;
				}
			
			return false;
		}
	},
	
	/** {@link ThreadShelf#toJavaThread(VMThreadBracket)}. */
	TO_JAVA_THREAD("toJavaThread:(Lcc/squirreljme/jvm/mle/" +
		"brackets/VMThreadBracket;)Ljava/lang/Thread;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			VMThreadObject vmThread = MLEThread.__vmThread(__args[0]);
			
			return vmThread.getThread().threadInstance();
		}
	}, 
	
	/** {@link ThreadShelf#toVMThread(Thread)}. */
	TO_VM_THREAD("toVMThread:(Ljava/lang/Thread;)Lcc/squirreljme/" +
		"jvm/mle/brackets/VMThreadBracket;")
	{
		/**
		 * {@inheritDoc}
................................................................................
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			VMThreadObject vmThread = MLEThread.__vmThread(__args[0]);
			
			// Send an interrupt to the thread
			vmThread.getThread().hardInterrupt();
			
			return null;
		}
	},
................................................................................
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEThread.__vmThread(__args[0]).getThread().isMain();
		}
	},
	
	/** {@link ThreadShelf#vmThreadSetPriority(VMThreadBracket, int)}. */
	VM_THREAD_SET_PRIORITY("vmThreadSetPriority:(Lcc/squirreljme/" +
		"jvm/mle/brackets/VMThreadBracket;I)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringThread thread = MLEThread.__vmThread(__args[0]).getThread();
			int priority = (int)__args[1];
			
			if (priority < Thread.MIN_PRIORITY ||
				priority > Thread.MAX_PRIORITY)
				throw new MLECallError("Thread priority out of bounds.");
			
			// Try to set the priority
			try
			{
				thread._worker.setPriority(priority);
			}
			catch (IllegalArgumentException|SecurityException e)
			{
				throw new MLECallError("Could not set priority.", e);
			}
			
			return null;
		}
	}, 
	
	/** {@link ThreadShelf#vmThreadStart(VMThreadBracket)}. */
	VM_THREAD_START("vmThreadStart:(Lcc/squirreljme/jvm/mle/brackets/" +
		"VMThreadBracket;)Z")
	{
		/**
		 * {@inheritDoc}
................................................................................
			}
			catch (IllegalThreadStateException ignored)
			{
				return false;
			}
		}
	},
	
	/** {@link ThreadShelf#waitForUpdate(int)}. */
	WAIT_FOR_UPDATE("waitForUpdate:(I)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int ms = (int)__args[0];
			
			if (ms < 0)
				throw new MLECallError("Negative milliseconds");
			
			// Waiting for nothing? just give up our slice
			if (ms == 0)
			{
				Thread.yield();
				return false;
			}
			
			// Wait until the monitor is hit
			SpringMachine machine = __thread.machine;
			synchronized (machine)
			{
				try
				{
					machine.wait(ms);
				}
				catch (InterruptedException e)
				{
					return true;
				}
			}
			
			// Assume not interrupted
			return false;
		}
	}, 
	
	/* End. */
	;
	
	/** The class which contains the thread starting point. */
	static final ClassName _START_CLASS =
		new ClassName("java/lang/__Start__");

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

7
8
9
10
11
12
13

14
15
16
17
18
19
20
...
203
204
205
206
207
208
209

























210
211
212
213
214
215
216
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.TypeShelf;
import cc.squirreljme.jvm.mle.brackets.TypeBracket;

import cc.squirreljme.vm.springcoat.brackets.JarPackageObject;
import cc.squirreljme.vm.springcoat.brackets.TypeObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassNotFoundException;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import java.util.Objects;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodNameAndType;
................................................................................
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new JarPackageObject(MLEType.__type(__args[0])
				.getSpringClass().inJar());
		}
	},

























	
	/** {@link TypeShelf#isArray(TypeBracket)}. */
	IS_ARRAY("isArray:(Lcc/squirreljme/jvm/mle/brackets/TypeBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18







>







 







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







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.TypeShelf;
import cc.squirreljme.jvm.mle.brackets.TypeBracket;
import cc.squirreljme.runtime.cldc.debug.Debugging;
import cc.squirreljme.vm.springcoat.brackets.JarPackageObject;
import cc.squirreljme.vm.springcoat.brackets.TypeObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassNotFoundException;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import java.util.Objects;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodNameAndType;
................................................................................
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new JarPackageObject(MLEType.__type(__args[0])
				.getSpringClass().inJar());
		}
	},
	
	/** {@link TypeShelf#interfaces(TypeBracket)}. */
	INTERFACES("interfaces:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)[Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringClass type = MLEType.__type(__args[0]).getSpringClass();
			
			SpringClass[] interfaces = type.interfaceClasses();
			int n = interfaces.length;
			
			SpringObject[] rv = new SpringObject[n];
			for (int i = 0; i < n; i++)
				rv[i] = new TypeObject(interfaces[i]);
			
			return __thread.asVMObjectArray(__thread.resolveClass(
				"[Lcc/squirreljme/jvm/mle/brackets/TypeBracket;"), rv);
		}
	}, 
	
	/** {@link TypeShelf#isArray(TypeBracket)}. */
	IS_ARRAY("isArray:(Lcc/squirreljme/jvm/mle/brackets/TypeBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18

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

17
18
19
20
21
22
23

24
25
26
27
28
29
30
...
176
177
178
179
180
181
182



183
184
185
186
187
188
189
...
268
269
270
271
272
273
274

275
276



277
278
279
280

281
282


















283
284
285
286
287
288
289
...
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
...
438
439
440
441
442
443
444












445
446
447
448
449
450
451
import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.vm.springcoat.exceptions.SpringFatalException;
import cc.squirreljme.vm.springcoat.exceptions.SpringMachineExitException;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;

import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValueString;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodNameAndType;
................................................................................
			SpringThread rv = new SpringThread(
				(v = ++this._nextthreadid), __main,
				usedName,
				this.profiler.measureThread(String.format("%s-vm%08x-%d-%s",
				this.classloader.bootLibrary().name(),
				System.identityHashCode(this), v, usedName)));
			



			// Store thread
			threads.add(rv);
			return rv;
		}
	}
	
	/**
................................................................................
	
	/**
	 * Returns all of the process threads.
	 *
	 * @return All of the current process threads.
	 * @since 2020/06/17
	 */

	public final SpringThread[] getThreads()
	{



		List<SpringThread> threads = this._threads;
		synchronized (this)
		{
			return threads.<SpringThread>toArray(

				new SpringThread[threads.size()]);
		}


















	}
	
	/**
	 * Returns the static field for the given field.
	 *
	 * @param __f The field to get the static field for.
	 * @return The static field.
................................................................................
		SpringThread mainThread = this.createThread("main", true);
		
		// We will be using the same logic in the thread worker if we need to
		// initialize any objects or arguments
		SpringThreadWorker worker = new SpringThreadWorker(this,
			mainThread, true);
		mainThread._worker = worker;




		
		// Initialize an instance of Thread for this thread, as this is
		// very important, the call to create VM threads will bind the instance
		// object and the vm thread together.
		worker.newInstance(
			new ClassName("java/lang/Thread"),
			new MethodDescriptor("(Ljava/lang/String;)V"),
			worker.asVMObject("main"));
		
		// Enter the main entry point which handles the thread logic
		mainThread.enterFrame(worker.loadClass(SpringMachine._START_CLASS)
			.lookupMethod(true, SpringMachine._MAIN_THREAD_METHOD));
		
		// 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.
		try
		{
			worker.run();
		}
................................................................................
	 * @param __exitCode The exit code to set.
	 * @since 2020/06/27
	 */
	public final void setExitCode(int __exitCode)
	{
		this._exitcode = __exitCode;
	}












	
	/**
	 * Returns the suite manager which is available.
	 *
	 * @return The suite manager that is available.
	 * @since 2018/10/26
	 */







>







 







>
>
>







 







>


>
>
>



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







 







>
>
>
>









<
<
<
<







 







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







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
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
...
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
...
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
import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.vm.springcoat.exceptions.SpringFatalException;
import cc.squirreljme.vm.springcoat.exceptions.SpringMachineExitException;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValueString;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodNameAndType;
................................................................................
			SpringThread rv = new SpringThread(
				(v = ++this._nextthreadid), __main,
				usedName,
				this.profiler.measureThread(String.format("%s-vm%08x-%d-%s",
				this.classloader.bootLibrary().name(),
				System.identityHashCode(this), v, usedName)));
			
			// Signal that a major state has changed
			this.notifyAll();
			
			// Store thread
			threads.add(rv);
			return rv;
		}
	}
	
	/**
................................................................................
	
	/**
	 * Returns all of the process threads.
	 *
	 * @return All of the current process threads.
	 * @since 2020/06/17
	 */
	@SuppressWarnings("UnnecessaryLocalVariable")
	public final SpringThread[] getThreads()
	{
		List<SpringThread> rv = new ArrayList<>();
		
		// Go through threads but also cleanup any that have ended
		List<SpringThread> threads = this._threads;
		synchronized (this)
		{
			for (Iterator<SpringThread> it = threads.iterator(); it.hasNext();)
			{
				SpringThread thread = it.next();
				
				// If the thread is terminating, clean it up
				if (thread.isTerminated())
				{
					// Remove it
					it.remove();
					
					// Signal that a state of a thread has changed
					this.notifyAll();
				}
				
				// Otherwise add it
				else
					rv.add(thread);
			}
		}
		
		// Use whatever was found
		return rv.<SpringThread>toArray(new SpringThread[rv.size()]);
	}
	
	/**
	 * Returns the static field for the given field.
	 *
	 * @param __f The field to get the static field for.
	 * @return The static field.
................................................................................
		SpringThread mainThread = this.createThread("main", true);
		
		// We will be using the same logic in the thread worker if we need to
		// initialize any objects or arguments
		SpringThreadWorker worker = new SpringThreadWorker(this,
			mainThread, true);
		mainThread._worker = worker;
		
		// Enter the main entry point which handles the thread logic
		mainThread.enterFrame(worker.loadClass(SpringMachine._START_CLASS)
			.lookupMethod(true, SpringMachine._MAIN_THREAD_METHOD));
		
		// Initialize an instance of Thread for this thread, as this is
		// very important, the call to create VM threads will bind the instance
		// object and the vm thread together.
		worker.newInstance(
			new ClassName("java/lang/Thread"),
			new MethodDescriptor("(Ljava/lang/String;)V"),
			worker.asVMObject("main"));
		




		// 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.
		try
		{
			worker.run();
		}
................................................................................
	 * @param __exitCode The exit code to set.
	 * @since 2020/06/27
	 */
	public final void setExitCode(int __exitCode)
	{
		this._exitcode = __exitCode;
	}
	
	/**
	 * Signals that the given thread terminated.
	 * 
	 * @param __thread The thread that was terminated.
	 * @since 2020/06/29
	 */
	public void signalThreadTerminate(SpringThread __thread)
	{
		// The act of getting all threads will clear out terminated threads
		this.getThreads();
	}
	
	/**
	 * Returns the suite manager which is available.
	 *
	 * @return The suite manager that is available.
	 * @since 2018/10/26
	 */

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

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77



78
79
80
81
82
83
84
...
119
120
121
122
123
124
125





126
127
128
129
130
131
132
...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
...
163
164
165
166
167
168
169





170
171
172
173
174
175
176
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
399
400
401
402
403
404
405














406
407
408
409
410
411
412
...
526
527
528
529
530
531
532




















533
534
535
536
537
538
539
	
	/** Ran at least one frame (was started)? */
	private volatile boolean _hadoneframe;
	
	/** Is this a daemon thread? */
	volatile boolean _daemon;
	
	/** Terminate the thread? */
	volatile boolean _terminate;
	
	/** Did we signal exit? */
	volatile boolean _signaledexit;
	
	/** The current worker for the thread. */
	volatile SpringThreadWorker _worker;
	



	/**
	 * Initializes the thread.
	 *
	 * @param __id The thread ID.
	 * @param __main Is this a main thread.
	 * @param __n The name of the thread.
	 * @param __profiler Profiled storage.
................................................................................
	 * Enters a blank frame to store data.
	 *
	 * @return The
	 * @since 2018/09/20
	 */
	public final SpringThread.Frame enterBlankFrame()
	{





		// Setup blank frame
		SpringThread.Frame rv = new SpringThread.Frame();
		
		// {@squirreljme.error BK1j Stack overflow.}
		List<SpringThread.Frame> frames = this._frames;
		if (frames.size() >= SpringThread.MAX_STACK_DEPTH)
			throw new SpringVirtualMachineException("BK1j");
................................................................................
		// Profile for this frame
		this.profiler.enterFrame("<blank>", "<blank>", "()V",
			System.nanoTime());
		
		// Had one frame (started)
		this._hadoneframe = true;
		
		// Undo termination
		this._terminate = false;
		
		return rv;
	}
	
	/**
	 * Enters the specified method and sets up a stack frame for it.
	 *
	 * @param __m The method to enter.
................................................................................
	public final SpringThread.Frame enterFrame(SpringMethod __m,
		Object... __args)
		throws NullPointerException, SpringVirtualMachineException
	{
		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));*/
		
................................................................................
		{
			frames.add(rv);
		}
		
		// Had one frame (started)
		this._hadoneframe = true;
		
		// Undo termination
		this._terminate = false;
		
		// Handle synchronized method
		if (__m.flags().isSynchronized())
		{
			SpringObject monitor;
			
			// Monitor on the class object, needs the worker since we need to
			// load a class
................................................................................
	 * @return If this is a main thread.
	 * @since 2020/06/17
	 */
	public final boolean isMain()
	{
		return this.main;
	}














	
	/**
	 * Returns the name of the thread.
	 *
	 * @return The name of the thread.
	 * @since 2018/09/03
	 */
................................................................................
		{
			if (this._vmThread != null)
				throw new IllegalStateException("Thread has VM Thread.");
			
			this._vmThread = __vmThread;
		}
	}




















	
	/**
	 * Returns the instance of the {@link Thread} object for this thread.
	 *
	 * @return The instance of {@link Thread}.
	 * @throws IllegalStateException If the thread has no instance.
	 * @since 2020/06/17







<
<
<






>
>
>







 







>
>
>
>
>







 







<
<
<







 







>
>
>
>
>







 







<
<
<







 







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







 







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







62
63
64
65
66
67
68



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
145
146
147
148
149
150
151



152
153
154
155
156
157
158
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
201
202
203
204
205
206
207



208
209
210
211
212
213
214
...
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
...
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
	
	/** Ran at least one frame (was started)? */
	private volatile boolean _hadoneframe;
	
	/** Is this a daemon thread? */
	volatile boolean _daemon;
	



	/** Did we signal exit? */
	volatile boolean _signaledexit;
	
	/** The current worker for the thread. */
	volatile SpringThreadWorker _worker;
	
	/** Terminate the thread? */
	private volatile boolean _terminate;
	
	/**
	 * Initializes the thread.
	 *
	 * @param __id The thread ID.
	 * @param __main Is this a main thread.
	 * @param __n The name of the thread.
	 * @param __profiler Profiled storage.
................................................................................
	 * Enters a blank frame to store data.
	 *
	 * @return The
	 * @since 2018/09/20
	 */
	public final SpringThread.Frame enterBlankFrame()
	{
		// Cannot enter frames when terminated
		if (this.isTerminated())
			throw new SpringVirtualMachineException(
				"Cannot enter frame on terminated thread.");
		
		// Setup blank frame
		SpringThread.Frame rv = new SpringThread.Frame();
		
		// {@squirreljme.error BK1j Stack overflow.}
		List<SpringThread.Frame> frames = this._frames;
		if (frames.size() >= SpringThread.MAX_STACK_DEPTH)
			throw new SpringVirtualMachineException("BK1j");
................................................................................
		// Profile for this frame
		this.profiler.enterFrame("<blank>", "<blank>", "()V",
			System.nanoTime());
		
		// Had one frame (started)
		this._hadoneframe = true;
		



		return rv;
	}
	
	/**
	 * Enters the specified method and sets up a stack frame for it.
	 *
	 * @param __m The method to enter.
................................................................................
	public final SpringThread.Frame enterFrame(SpringMethod __m,
		Object... __args)
		throws NullPointerException, SpringVirtualMachineException
	{
		if (__m == null)
			throw new NullPointerException("NARG");
		
		// Cannot enter frames when terminated
		if (this.isTerminated())
			throw new SpringVirtualMachineException(
				"Cannot enter frame on terminated thread.");
		
		if (__args == null)
			__args = new Object[0];
		
		// Debug
		/*todo.DEBUG.note("enterFrame(%s::%s, %s)", __m.inClass(),
			__m.nameAndType(), Arrays.<Object>asList(__args));*/
		
................................................................................
		{
			frames.add(rv);
		}
		
		// Had one frame (started)
		this._hadoneframe = true;
		



		// Handle synchronized method
		if (__m.flags().isSynchronized())
		{
			SpringObject monitor;
			
			// Monitor on the class object, needs the worker since we need to
			// load a class
................................................................................
	 * @return If this is a main thread.
	 * @since 2020/06/17
	 */
	public final boolean isMain()
	{
		return this.main;
	}
	
	/**
	 * Returns if this thread has terminated.
	 * 
	 * @return If this thread has terminated.
	 * @since 2020/06/29
	 */
	public final boolean isTerminated()
	{
		synchronized (this)
		{
			return this._terminate;
		}
	}
	
	/**
	 * Returns the name of the thread.
	 *
	 * @return The name of the thread.
	 * @since 2018/09/03
	 */
................................................................................
		{
			if (this._vmThread != null)
				throw new IllegalStateException("Thread has VM Thread.");
			
			this._vmThread = __vmThread;
		}
	}
	
	/**
	 * Terminates this thread.
	 * 
	 * @since 2020/06/29
	 */
	public final void terminate()
	{
		// Terminates this thread
		synchronized (this)
		{
			// Set as terminated
			this._terminate = true;
		}
		
		// Signal to the machine that this thread terminated
		SpringThreadWorker worker = this._worker;
		if (worker != null)
			worker.machine.signalThreadTerminate(this);
	}
	
	/**
	 * Returns the instance of the {@link Thread} object for this thread.
	 *
	 * @return The instance of {@link Thread}.
	 * @throws IllegalStateException If the thread has no instance.
	 * @since 2020/06/17

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

1140
1141
1142
1143
1144
1145
1146
1147



1148
1149
1150
1151
1152
1153
1154
1155
1156
....
1161
1162
1163
1164
1165
1166
1167



1168
1169
1170
1171
1172
1173
1174
....
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
....
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
....
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
				this.__singleStep();
			}
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{



			// Thread is okay to exit!
			thread._terminate = true;
			thread._signaledexit = true;
			
			// Exit all frames
			thread.exitAllFrames();
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
................................................................................
		
		// Caught exception
		catch (RuntimeException e)
		{
			// Frame limit is zero, so kill the thread
			if (__framelimit == 0)
			{



				PrintStream err = System.err;
				
				err.println("****************************");
				
				// Print the real stack trace
				err.println("*** EXTERNAL STACK TRACE ***");
				e.printStackTrace(err);
................................................................................
				// Print the VM seen stack trace
				err.println("*** INTERNAL STACK TRACE ***");
				thread.printStackTrace(err);
				err.println();
				
				err.println("****************************");
				
				// Terminate the thread
				thread._terminate = true;
				
				// Exit all frames
				thread.exitAllFrames();
				
				// Exit from all profiler threads
				thread.profiler.exitAll(System.nanoTime());
			}
			
................................................................................
			throw e;
		}
		
		// Terminate if the last frame
		finally
		{
			if (__framelimit == 0)
				thread._terminate = true;
		}
	}
	
	/**
	 * Run the main process for this thread.
	 *
	 * @since 2020/06/17
................................................................................
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{
			// Thread is okay to exit!
			thread._terminate = true;
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
			
			throw e;
		}
		







|
>
>
>

<







 







>
>
>







 







<
<
<







 







|







 







|







1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151

1152
1153
1154
1155
1156
1157
1158
....
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
....
1182
1183
1184
1185
1186
1187
1188



1189
1190
1191
1192
1193
1194
1195
....
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
....
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
				this.__singleStep();
			}
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{	
			// Terminate the thread
			thread.terminate();
			
			// Thread is okay to exit!

			thread._signaledexit = true;
			
			// Exit all frames
			thread.exitAllFrames();
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
................................................................................
		
		// Caught exception
		catch (RuntimeException e)
		{
			// Frame limit is zero, so kill the thread
			if (__framelimit == 0)
			{
				// Terminate the thread
				thread.terminate();
				
				PrintStream err = System.err;
				
				err.println("****************************");
				
				// Print the real stack trace
				err.println("*** EXTERNAL STACK TRACE ***");
				e.printStackTrace(err);
................................................................................
				// Print the VM seen stack trace
				err.println("*** INTERNAL STACK TRACE ***");
				thread.printStackTrace(err);
				err.println();
				
				err.println("****************************");
				



				// Exit all frames
				thread.exitAllFrames();
				
				// Exit from all profiler threads
				thread.profiler.exitAll(System.nanoTime());
			}
			
................................................................................
			throw e;
		}
		
		// Terminate if the last frame
		finally
		{
			if (__framelimit == 0)
				thread.terminate();
		}
	}
	
	/**
	 * Run the main process for this thread.
	 *
	 * @since 2020/06/17
................................................................................
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{
			// Thread is okay to exit!
			thread.terminate();
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
			
			throw e;
		}
		

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

6
7
8
9
10
11
12

13
14
15
16
17
18
19
..
31
32
33
34
35
36
37

38
39
40

41
42
43
44
45
46
47
..
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
...
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
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.brackets.VMThreadBracket;


/**
 * This shelf handles everything regarding threading and otherwise.
 *
 * @see VMThreadBracket
 * @since 2020/06/17
 */
................................................................................
		boolean __includeDaemon);
	
	/**
	 * Creates a virtual machine thread for the given Java thread.
	 *
	 * @param __javaThread The Java thread to create under.
	 * @return The virtual machine thread.

	 * @since 2020/06/17
	 */
	public static native VMThreadBracket createVMThread(Thread __javaThread);

	
	/**
	 * Returns the current Java thread.
	 *
	 * @return The current {@link Thread}.
	 * @since 2020/06/17
	 */
................................................................................
	public static native int currentExitCode();
	
	/**
	 * Returns whether the interrupt flag was raised and clears it.
	 *
	 * @param __javaThread The Java thread.
	 * @return If the thread was interrupted.

	 * @since 2020/06/17
	 */
	public static native boolean javaThreadClearInterrupt(Thread __javaThread);

	
	/**
	 * Marks the thread as being started.
	 *
	 * @param __javaThread The thread to mark started.

	 * @since 2020/06/17
	 */
	public static native void javaThreadFlagStarted(Thread __javaThread);

	
	/**
	 * Has this Java thread been started?
	 *
	 * @param __javaThread The Java thread.
	 * @return If this thread has been started.

	 * @since 2020/06/17
	 */
	public static native boolean javaThreadIsStarted(Thread __javaThread);

	
	/**
	 * Returns the runnable for the given Java thread.
	 *
	 * @param __javaThread The Java thread.
	 * @return The {@link Runnable} for the given thread.

	 * @since 2020/06/17
	 */
	public static native Runnable javaThreadRunnable(Thread __javaThread);

	
	/**
	 * Sets if the thread is alive or not.
	 *
	 * @param __javaThread The Java thread.
	 * @param __set If this is to be alive or not. If this is {@code true}
	 * then the active count goes up, otherwise it shall go down.

	 * @since 2020/06/17
	 */
	public static native void javaThreadSetAlive(Thread __javaThread,
		boolean __set);

	
	/**
	 * Runs the main entry point for the current process and gives it all of
	 * the arguments that were specified on program initialization.
	 *
	 * @since 2020/06/17
	 */
................................................................................
	 * @since 2020/06/17
	 */
	public static native void setCurrentExitCode(int __code);
	
	/**
	 * Sleeps the current thread for the given amount of time.
	 *
	 * If both times are zero, this means to yield.

	 *
	 * @param __ms The number of milliseconds.
	 * @param __ns The number of nanoseconds.
	 * @return {@code true} if the thread was interrupted.


	 * @since 2020/06/17
	 */
	public static native boolean sleep(int __ms, int __ns);

	
	/**
	 * Returns the Java thread for the VM thread.
	 *
	 * @param __thread The VM thread.
	 * @return The Java thread which belongs to this thread.

	 * @since 2020/06/17
	 */
	public static native Thread toJavaThread(VMThreadBracket __thread);

	
	/**
	 * Returns the virtual machine thread from the given Java thread.
	 *
	 * @param __thread The Java thread.
	 * @return The VM thread for this thread.

	 * @since 2020/06/17
	 */
	public static native VMThreadBracket toVMThread(Thread __thread);

	
	/**
	 * Returns the thread ID for the given thread.
	 *
	 * @param __vmThread The virtual machine thread.
	 * @return The thread ID.

	 * @since 2020/06/17
	 */
	public static native int vmThreadId(VMThreadBracket __vmThread);

	
	/**
	 * Performs a hardware interrupt on the thread.
	 *
	 * @param __vmThread The virtual machine thread.

	 * @since 2020/06/17
	 */
	public static native void vmThreadInterrupt(VMThreadBracket __vmThread);

	
	/**
	 * Checks if the given thread is a main thread.
	 *
	 * @param __vmThread The thread to check.
	 * @return {@code true} if the given thread is a main thread.

	 * @since 2020/06/17
	 */
	public static native boolean vmThreadIsMain(VMThreadBracket __vmThread);

	
	/**
	 * Sets the thread priority.

	 *



	 * @param __vmThread The virtual machine thread.
	 * @param __p The priority to set.




	 * @since 2020/06/17
	 */
	public static native void vmThreadSetPriority(VMThreadBracket __vmThread,
		int __p);

	
	/**
	 * Performs the actual start of the given thread.
	 *
	 * @param __vmThread The thread to start.
	 * @return If the start of the thread succeeded.

	 * @since 2020/06/17
	 */
	public static native boolean vmThreadStart(VMThreadBracket __vmThread);

	
	/**
	 * Waits for the state of threads to be updated, or just times out.
	 *
	 * A thread update is when another thread becomes alive, becomes dead,
	 * or is started.
	 *
	 * @param __ms The amount of time to wait for.


	 * @since 2020/06/17
	 */
	public static native void waitForUpdate(int __ms);

}







>







 







>


|
>







 







>


|
>





>


|
>






>


|
>






>


|
>







>



|
>







 







|
>




>
>


|
>




|

>


|
>






>


|
>






>


|
>





>


|
>






>


|
>


|
>
|
>
>
>

|
>
>
>
>



|
>






>


|
>








>
>


|
>

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
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
...
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
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.brackets.VMThreadBracket;
import cc.squirreljme.jvm.mle.exceptions.MLECallError;

/**
 * This shelf handles everything regarding threading and otherwise.
 *
 * @see VMThreadBracket
 * @since 2020/06/17
 */
................................................................................
		boolean __includeDaemon);
	
	/**
	 * Creates a virtual machine thread for the given Java thread.
	 *
	 * @param __javaThread The Java thread to create under.
	 * @return The virtual machine thread.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native VMThreadBracket createVMThread(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Returns the current Java thread.
	 *
	 * @return The current {@link Thread}.
	 * @since 2020/06/17
	 */
................................................................................
	public static native int currentExitCode();
	
	/**
	 * Returns whether the interrupt flag was raised and clears it.
	 *
	 * @param __javaThread The Java thread.
	 * @return If the thread was interrupted.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean javaThreadClearInterrupt(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Marks the thread as being started.
	 *
	 * @param __javaThread The thread to mark started.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native void javaThreadFlagStarted(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Has this Java thread been started?
	 *
	 * @param __javaThread The Java thread.
	 * @return If this thread has been started.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean javaThreadIsStarted(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Returns the runnable for the given Java thread.
	 *
	 * @param __javaThread The Java thread.
	 * @return The {@link Runnable} for the given thread.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native Runnable javaThreadRunnable(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Sets if the thread is alive or not.
	 *
	 * @param __javaThread The Java thread.
	 * @param __set If this is to be alive or not. If this is {@code true}
	 * then the active count goes up, otherwise it shall go down.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native void javaThreadSetAlive(Thread __javaThread,
		boolean __set)
		throws MLECallError;
	
	/**
	 * Runs the main entry point for the current process and gives it all of
	 * the arguments that were specified on program initialization.
	 *
	 * @since 2020/06/17
	 */
................................................................................
	 * @since 2020/06/17
	 */
	public static native void setCurrentExitCode(int __code);
	
	/**
	 * Sleeps the current thread for the given amount of time.
	 *
	 * If both times are zero, this means to yield the thread (give up its
	 * current execution context).
	 *
	 * @param __ms The number of milliseconds.
	 * @param __ns The number of nanoseconds.
	 * @return {@code true} if the thread was interrupted.
	 * @throws MLECallError If either value is negative or the nanoseconds is
	 * out of range.
	 * @since 2020/06/17
	 */
	public static native boolean sleep(int __ms, int __ns)
		throws MLECallError;
	
	/**
	 * Returns the Java thread for the VM thread.
	 *
	 * @param __vmThread The VM thread.
	 * @return The Java thread which belongs to this thread.
	 * @throws MLECallError If {@code __thread} is null.
	 * @since 2020/06/17
	 */
	public static native Thread toJavaThread(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Returns the virtual machine thread from the given Java thread.
	 *
	 * @param __thread The Java thread.
	 * @return The VM thread for this thread.
	 * @throws MLECallError If {@code __thread} is null.
	 * @since 2020/06/17
	 */
	public static native VMThreadBracket toVMThread(Thread __thread)
		throws MLECallError;
	
	/**
	 * Returns the thread ID for the given thread.
	 *
	 * @param __vmThread The virtual machine thread.
	 * @return The thread ID.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native int vmThreadId(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Performs a hardware interrupt on the thread.
	 *
	 * @param __vmThread The virtual machine thread.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native void vmThreadInterrupt(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Checks if the given thread is a main thread.
	 *
	 * @param __vmThread The thread to check.
	 * @return {@code true} if the given thread is a main thread.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean vmThreadIsMain(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Sets the thread priority in the same manner as
	 * {@link Thread#setPriority(int)} if this is supported by the hardware.
	 * 
	 * This may or may not be supported and should only be used as a hint and
	 * not a guarantee.
	 *
	 * @param __vmThread The virtual machine thread.
	 * @param __p The priority to set, this will be the same as
	 * {@link Thread#setPriority(int)}.
	 * @throws MLECallError If {@code __vmThread} is null or {@code __p} is
	 * not within {@link Thread#MIN_PRIORITY} and {@link Thread#MAX_PRIORITY}
	 * inclusive.
	 * @since 2020/06/17
	 */
	public static native void vmThreadSetPriority(VMThreadBracket __vmThread,
		int __p)
		throws MLECallError;
	
	/**
	 * Performs the actual start of the given thread.
	 *
	 * @param __vmThread The thread to start.
	 * @return If the start of the thread succeeded.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean vmThreadStart(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Waits for the state of threads to be updated, or just times out.
	 *
	 * A thread update is when another thread becomes alive, becomes dead,
	 * or is started.
	 *
	 * @param __ms The amount of time to wait for.
	 * @return If the thread was interrupted while waiting.
	 * @throws MLECallError If {@code __ms} is negative.
	 * @since 2020/06/17
	 */
	public static native boolean waitForUpdate(int __ms)
		throws MLECallError;
}

Changes to modules/cldc-compact/src/test/java/squirreljme/mle/errors/TestThreadShelfInvalid.java.

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
..
93
94
95
96
97
98
99





100
101
102
103
104
105
106
107
				break;
			
			case 10:
				ThreadShelf.vmThreadInterrupt(null);
				break;
			
			case 11:
				ThreadShelf.vmThreadSetPriority(null, -1);

				break;
			
			case 12:
				ThreadShelf.vmThreadStart(null);
				break;
			
			case 13:
................................................................................
			case 15:
				ThreadShelf.sleep(0, -1234);
				break;
			
			case 16:
				ThreadShelf.sleep(0, Integer.MAX_VALUE);
				break;





			
			default:
				return true;
		}
		
		return false;
	}
}







|
>







 







>
>
>
>
>








71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
..
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
				break;
			
			case 10:
				ThreadShelf.vmThreadInterrupt(null);
				break;
			
			case 11:
				ThreadShelf.vmThreadSetPriority(null, 
					Thread.MIN_PRIORITY - 1);
				break;
			
			case 12:
				ThreadShelf.vmThreadStart(null);
				break;
			
			case 13:
................................................................................
			case 15:
				ThreadShelf.sleep(0, -1234);
				break;
			
			case 16:
				ThreadShelf.sleep(0, Integer.MAX_VALUE);
				break;
			
			case 17:
				ThreadShelf.vmThreadSetPriority(null, 
					Thread.MAX_PRIORITY + 1);
				break;
			
			default:
				return true;
		}
		
		return false;
	}
}

Changes to modules/cldc-compact/src/test/resources/squirreljme/mle/errors/TestThreadShelfInvalid.in.

1
result: int:17
|
1
result: int:18

Changes to modules/cldc-compact/src/test/resources/squirreljme/mle/errors/TestTypeShelfInvalid.in.

1
result: int:16
|
1
result: int:18