Check-in [f09d7f9d04]

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

Overview
Comment:Add new API base for the ability to launch commands with system properties and console redirection as well.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:f09d7f9d0487c47da75266a270c2252fa45de5b0
User & Date: stephanie.gawroriski 2019-02-03 00:24:45
Context
2019-02-03
08:02
Backup developer notes. check-in: 3ce32d1a0a user: squirreljme tags: trunk
00:24
Add new API base for the ability to launch commands with system properties and console redirection as well. check-in: f09d7f9d04 user: stephanie.gawroriski tags: trunk
2019-02-02
15:03
Base read of get static. check-in: 508f5f8d86 user: stephanie.gawroriski tags: trunk, x-date-201902
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to changelog.mkd.

29
30
31
32
33
34
35



36
37
38
39
40
41
42
..
50
51
52
53
54
55
56


57
58
59
60
61
62
63
     * `java.io.InputStream`
     * `java.util.EventObject`
     * `java.util.LinkedList`
   * Deprecations
     * `net.multiphasicapps.classfile.ExecutableCode`, not used.
   * Additions
     * `java.util.Vector`, was missing.



 * Programs and Libraries
   * `demo-hello`
     * Made the system properties array `final`.
   * `tac`
     * Override standard output and forward to standard error while a test is
       running, so things are not kludged.
   * `tac-runner`
................................................................................
 * Virtual Machines
   * General
     * Adjusted the Shaded JAR directory layout and added a dash in the path
       so that classes technically become invalid.
     * Allow properties to be obtained from internally passed system
       properties.
     * Added string representation for the stack map table.


   * SpringCoat
     * Add support for system properties being based to virtual machine
       instances.
     * Profiler thread lists are easier to read because the main suite is
       listed instead of the VM identifier.
   * SummerCoat
     * New Virtual Machine, register based.







>
>
>







 







>
>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
     * `java.io.InputStream`
     * `java.util.EventObject`
     * `java.util.LinkedList`
   * Deprecations
     * `net.multiphasicapps.classfile.ExecutableCode`, not used.
   * Additions
     * `java.util.Vector`, was missing.
     * Added proprietary `ExtendedTaskManager` interface which can be used
       to specify arguments, system properties, and console output alternatives
       to launched tasks.
 * Programs and Libraries
   * `demo-hello`
     * Made the system properties array `final`.
   * `tac`
     * Override standard output and forward to standard error while a test is
       running, so things are not kludged.
   * `tac-runner`
................................................................................
 * Virtual Machines
   * General
     * Adjusted the Shaded JAR directory layout and added a dash in the path
       so that classes technically become invalid.
     * Allow properties to be obtained from internally passed system
       properties.
     * Added string representation for the stack map table.
     * Add ability to start tasks with command line arguments, system
       properties, and alternative console redirection (to capture output).
   * SpringCoat
     * Add support for system properties being based to virtual machine
       instances.
     * Profiler thread lists are easier to read because the main suite is
       listed instead of the VM identifier.
   * SummerCoat
     * New Virtual Machine, register based.

Added runt/apis/cldc-compact/cc/squirreljme/runtime/cldc/asm/ConsoleCallback.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
// -*- 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.runtime.cldc.asm;

import java.io.IOException;

/**
 * This is the callback used for the console.
 *
 * @since 2019/02/02
 */
public interface ConsoleCallback
{
	/**
	 * This is called when the stream has been closed.
	 *
	 * @return {@code false} if an {@link IOException} occurred.
	 * @since 2019/02/02
	 */
	public abstract boolean close();
	
	/**
	 * This is called when the callback is flushed.
	 *
	 * @return {@code false} if an {@link IOException} occurred.
	 * @since 2019/02/02
	 */
	public abstract boolean flush();
	
	/**
	 * Writes the specified bytes to the output.
	 *
	 * @param __b The bytes to write.
	 * @param __o The offset.
	 * @param __l The length.
	 * @return {@code false} if an {@link IOException} occurred.
	 * @since 2019/02/02
	 */
	public abstract boolean write(byte[] __b, int __o, int __l);
}

Changes to runt/apis/cldc-compact/cc/squirreljme/runtime/cldc/asm/TaskAccess.java.

93
94
95
96
97
98
99





















100
101
102
103
104
105
106
	 * not start.
	 * @since 2018/11/04
	 */
	@Api(ApiLevel.LEVEL_SQUIRRELJME_0_2_0_20181225)
	public static final native int startTask(String[] __cp, String __main,
		String[] __args);
	





















	/**
	 * Starts the given thread.
	 *
	 * @param __t The thread which is to run, the execution point of the
	 * thread is the {@link Thread#__start()} method.
	 * @param __n The name hint of this thread.
	 * @return The thread ID.







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







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
	 * not start.
	 * @since 2018/11/04
	 */
	@Api(ApiLevel.LEVEL_SQUIRRELJME_0_2_0_20181225)
	public static final native int startTask(String[] __cp, String __main,
		String[] __args);
	
	/**
	 * Starts the specified task.
	 *
	 * @param __cp The classpath used.
	 * @param __main The main entry point.
	 * @param __args Arguments to start the task with.
	 * @param __sprops System properties in key/value pairs to pass to the
	 * target environment.
	 * @param __stdout Callback to receive standard output data, may be
	 * {@code null} to ignore.
	 * @param __stderr Callback to receive standard error data, may be
	 * {@code null} to ignore.
	 * @return The task identifier or a negative number if the task could
	 * not start.
	 * @since 2019/02/02
	 */
	@Api(ApiLevel.LEVEL_SQUIRRELJME_0_3_0_DEV)
	public static final native int startTask(String[] __cp, String __main,
		String[] __args, String[] __sprops, ConsoleCallback __stdout,
		ConsoleCallback __stderr);
	
	/**
	 * Starts the given thread.
	 *
	 * @param __t The thread which is to run, the execution point of the
	 * thread is the {@link Thread#__start()} method.
	 * @param __n The name hint of this thread.
	 * @return The thread ID.

Changes to runt/apis/cldc-compact/cc/squirreljme/runtime/cldc/lang/ApiLevel.java.

62
63
64
65
66
67
68
69


70










		return String.format("%d.%d.%d (Day %d of %d)",
			(__l / 100000000) % 10,
			(__l / 1000000) % 100,
			(__l / 100000) % 10,
			__l % 1000,
			2000 + ((__l / 1000) % 100));
	}
}




















|
>
>
|
>
>
>
>
>
>
>
>
>
>
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
		return String.format("%d.%d.%d (Day %d of %d)",
			(__l / 100000000) % 10,
			(__l / 1000000) % 100,
			(__l / 100000) % 10,
			__l % 1000,
			2000 + ((__l / 1000) % 100));
	}
	
	/**
	 * Checks if the runtime API level is at a minimum this given level.
	 *
	 * @param __l The level to check.
	 * @return If the minimum level is met.
	 * @since 2019/02/02
	 */
	public static boolean minimumLevel(int __l)
	{
		return (SystemProperties.apiLevel() >= __l);
	}
}

Added runt/apis/meep-swm/cc/squirreljme/runtime/swm/ExtendedTaskManager.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
// -*- 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.runtime.swm;

import java.io.OutputStream;
import java.util.Map;
import javax.microedition.swm.Suite;
import javax.microedition.swm.Task;

/**
 * This interface is used for providing the ability to launch tasks.
 *
 * @since 2019/02/02
 */
public interface ExtendedTaskManager
{
	/**
	 * Attempts to create a task which runs the given suite.
	 *
	 * The task is created and is initially in the {@link TaskStatus#STARTING}
	 * state. If starting fails then it enters the
	 * {@link TaskStatus#START_FAILED} state.
	 *
	 * A suite may only be active once and cannot have multiple copies running
	 * at the same time. In the event that an application is already running it
	 * must be sent an event specifying an application re-launch.
	 *
	 * This is an extended method which allows more advanced control over the
	 * task such as including arguments, system properties, and potential
	 * output redirection.
	 *
	 * @param __s The suite to start, must be an application.
	 * @param __cn The class which extends
	 * {@link javax.microedition.midlet.MIDlet} and acts as the main entry
	 * point for the program.
	 * @param __sprops System properties to pass to the started task.
	 * @param __args Arguments to pass to the called program.
	 * @param __stdout Alternative {@link System#out}.
	 * @param __stderr Alternative {@link System#err}.
	 * @return The task which was created.
	 * @throws IllegalArgumentException If the suite is a library, the given
	 * class does not exist, or the given class does not extend
	 * {@link javax.microedition.midlet.MIDlet}.
	 * @throws IllegalStateException If the suite has been removed.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/02/02
	 */
	public abstract Task startTask(Suite __s, String __cn,
		Map<String, String> __sprops, String[] __args, OutputStream __stdout,
		OutputStream __stderr)
		throws IllegalArgumentException, IllegalStateException,
			NullPointerException;
}

Added runt/apis/meep-swm/javax/microedition/swm/__CCWrapper__.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
// -*- 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 javax.microedition.swm;

import cc.squirreljme.runtime.cldc.asm.ConsoleCallback;
import java.io.IOException;
import java.io.OutputStream;

/**
 * This is a wrapper for when a task writes to its console, this will be
 * called which just forwards to the output stream specified.
 *
 * @since 2019/02/02
 */
final class __CCWrapper__
	implements ConsoleCallback
{
	/** The stream to forward to. */
	protected final OutputStream out;
	
	/**
	 * Initializes the wrapper to the given stream.
	 *
	 * @param __out The stream to write to.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/02/02
	 */
	__CCWrapper__(OutputStream __out)
		throws NullPointerException
	{
		if (__out == null)
			throw new NullPointerException("NARG");
		
		this.out = __out;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/02/02
	 */
	@Override
	public final boolean close()
	{
		try
		{
			this.out.close();
			return true;
		}
		catch (IOException e)
		{
			return false;
		}
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/02/02
	 */
	@Override
	public final boolean flush()
	{
		try
		{
			this.out.flush();
			return true;
		}
		catch (IOException e)
		{
			return false;
		}
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/02/02
	 */
	@Override
	public final boolean write(byte[] __b, int __o, int __l)
	{
		try
		{
			this.out.write(__b, __o, __l);
			return true;
		}
		catch (IOException e)
		{
			return false;
		}
	}
}

Changes to runt/apis/meep-swm/javax/microedition/swm/__SystemTaskManager__.java.

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
...
129
130
131
132
133
134
135
136















137
138

















139
140
141
142
143
144
145
...
158
159
160
161
162
163
164
165























166


167
168
169
170
171
172
173
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package javax.microedition.swm;

import cc.squirreljme.runtime.cldc.asm.TaskAccess;

import cc.squirreljme.runtime.swm.DependencyInfo;

import cc.squirreljme.runtime.swm.MatchResult;
import cc.squirreljme.runtime.swm.ProvidedInfo;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This is the task manager which interfaces with the CLDC system support
 * methods to provide access to tasks and such.
 *
 * @since 2017/12/07
 */
final class __SystemTaskManager__
	implements TaskManager
{
	/** Mapping of task IDs to tasks. */
	static final Map<Integer, Task> _TASKS =
		new HashMap<>();
	
	/** Internal lock for chore management. */
	protected final Object lock =
................................................................................
	 * {@inheritDoc}
	 * @since 2018/10/29
	 */
	@Override
	public Task startTask(Suite __s, String __cn)
		throws IllegalArgumentException, IllegalStateException,
			NullPointerException
	{















		if (__s == null || __cn == null)
			throw new NullPointerException("NARG");

















		
		// {@squirreljme.error DG0w Cannot start a non-application suite.}
		if (__s.getSuiteType() != SuiteType.APPLICATION)
			throw new IllegalArgumentException("DG0w");
		
		// Get all the suites that are available, since we need to determine
		// dependencies and such
................................................................................
		
		// Add our boot suite to the last entry
		names[n] = __s._name;
		
		// Debug
		todo.DEBUG.note("Suites: %s", Arrays.<String>asList(names));
		
		// Setup new task internally























		int tid = TaskAccess.startTask(names, __cn, new String[0]);


		if (tid < 0)
		{
			// {@squirreljme.error DG0x Invalid entry point was specified
			// when starting task. (The entry point)}
			if (tid == TaskAccess.ERROR_INVALID_ENTRY)
				throw new IllegalArgumentException("DG0x " + __cn);
			







>

>


>







>












|







 








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


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







 







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







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

package javax.microedition.swm;

import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.runtime.cldc.lang.ApiLevel;
import cc.squirreljme.runtime.swm.DependencyInfo;
import cc.squirreljme.runtime.swm.ExtendedTaskManager;
import cc.squirreljme.runtime.swm.MatchResult;
import cc.squirreljme.runtime.swm.ProvidedInfo;
import java.io.OutputStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This is the task manager which interfaces with the CLDC system support
 * methods to provide access to tasks and such.
 *
 * @since 2017/12/07
 */
final class __SystemTaskManager__
	implements ExtendedTaskManager, TaskManager
{
	/** Mapping of task IDs to tasks. */
	static final Map<Integer, Task> _TASKS =
		new HashMap<>();
	
	/** Internal lock for chore management. */
	protected final Object lock =
................................................................................
	 * {@inheritDoc}
	 * @since 2018/10/29
	 */
	@Override
	public Task startTask(Suite __s, String __cn)
		throws IllegalArgumentException, IllegalStateException,
			NullPointerException
	{
		// Forward to the extended task start
		return this.startTask(__s, __cn, null, null, null, null);
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/02/02
	 */
	@Override
	public final Task startTask(Suite __s, String __cn,
		Map<String, String> __sprops, String[] __args, OutputStream __stdout,
		OutputStream __stderr)
		throws IllegalArgumentException, IllegalStateException,
			NullPointerException
	{
		if (__s == null || __cn == null)
			throw new NullPointerException("NARG");
		
		// Defensive copies
		__args = (__args == null ? new String[0] : __args.clone());
		__sprops = (__sprops == null ? new HashMap<String, String>() :
			new HashMap<String, String>(__sprops));
		
		// Make sure values are actually valid
		for (int i = 0, n = __args.length; i < n; i++)
			if (__args[i] == null)
				throw new NullPointerException("NARG");
		for (Map.Entry<String, String> e : __sprops.entrySet())
		{
			String k = e.getKey(),
				v = e.getValue();
			if (k == null || v == null)
				throw new NullPointerException("NARG");
		}
		
		// {@squirreljme.error DG0w Cannot start a non-application suite.}
		if (__s.getSuiteType() != SuiteType.APPLICATION)
			throw new IllegalArgumentException("DG0w");
		
		// Get all the suites that are available, since we need to determine
		// dependencies and such
................................................................................
		
		// Add our boot suite to the last entry
		names[n] = __s._name;
		
		// Debug
		todo.DEBUG.note("Suites: %s", Arrays.<String>asList(names));
		
		// SquirrelJME 0.3.0 allows system properties and alternative output
		// streams to be specified as well
		int tid;
		if (ApiLevel.minimumLevel(ApiLevel.LEVEL_SQUIRRELJME_0_3_0_DEV))
		{
			// Copy system properties to key/value pair array
			int spn = __sprops.size();
			String[] xprops = new String[spn * 2];
			Iterator<Map.Entry<String, String>> eit = __sprops.entrySet().
				iterator();
			for (int i = 0, o = 0; i < spn; i++, o += 2)
			{
				Map.Entry<String, String> e = eit.next();
				
				xprops[o] = e.getKey();
				xprops[o + 1] = e.getValue();
			}
			
			// Forward launch
			tid = TaskAccess.startTask(names, __cn, __args, xprops,
				(__stdout == null ? null : new __CCWrapper__(__stdout)),
				(__stderr == null ? null : new __CCWrapper__(__stderr)));
		}
		else
			tid = TaskAccess.startTask(names, __cn, __args);
		
		// It did not work
		if (tid < 0)
		{
			// {@squirreljme.error DG0x Invalid entry point was specified
			// when starting task. (The entry point)}
			if (tid == TaskAccess.ERROR_INVALID_ENTRY)
				throw new IllegalArgumentException("DG0x " + __cn);