Commit 9ef51e42 authored by Stephanie Gawroriski's avatar Stephanie Gawroriski
Browse files

Bring in base emulator and SpringCoat changes.

parent 453f9d49
Pipeline #39176 passed with stages
in 1 minute and 28 seconds
......@@ -197,6 +197,12 @@ The following _System_ properties are available:
* If only `:port` is specified it will listen for incoming connections from
a debugger.
* If both `hostname:port` is specified it will connect to a remote debugger.
* Note that if the hosted environment is debugged, launched sub-tasks will
not be run under the debugger.
* `squirreljme.xjdwp=[hostname]:port` -- Enable JDWP for Hosted environment.
* Does the same as `squirreljme.jdwp` but takes priority if both are
specified in the event that debugging should be done for the hosted
process.
* `squirreljme.midlet=value` -- The MIDlet to run, in the following order:
* If `value` is a number and is `-1`, then no MIDlet will be selected and
the `Main-Class` attribute will be force selected.
......@@ -212,6 +218,9 @@ The following _System_ properties are available:
* As an example `squirreljme.sysprop.favorite.animal=squirrel`:
* Will define system property `favorite.animal=squirrel` within the
virtual machine.
* `squirreljme.thread=value` -- The threading model to use.
* `single` or `coop` -- Single Cooperatively Threaded.
* `multi` or `smt` -- Simultaneous Multi-Threading.
* `test.single=classname` -- Run only the given test:
* Will be the test class to be run.
* Multi-parameter tests are in the form of `classname@parameter`, if a
......
......@@ -24,13 +24,6 @@ compileJava
// try to use them during compilation.
dependencies
{
// SquirrelJME just uses TestNG here since it is flexible enough to
// support how SquirrelJME needs to be (testing more as if it were running
// on the target device). Due to the flexibility it allows easier switching
// from Java SE, SpringCoat, and SummerCoat
compileClasspath "org.testng:testng:7.1.0"
runtimeClasspath "org.testng:testng:7.1.0"
// We need these two modules to obtain the SquirrelJME specific classes
compileClasspath project(":modules:cldc-compact")
compileClasspath project(":modules:common-vm")
......
......@@ -3,11 +3,9 @@
dependencies
{
// Need TestNG to run our tests
testImplementation "org.testng:testng:7.1.0"
// Needed to access all of the testing framework details
testImplementation project(":modules:cldc-compact")
testImplementation project(":modules:common-vm")
testImplementation project(":modules:tac")
testImplementation project(":modules:meep-midlet")
testImplementation project(":emulators:emulator-base")
......
......@@ -12,10 +12,18 @@
// The class to forward to
#define JARSHELF_CLASSNAME "cc/squirreljme/emulator/EmulatedJarPackageShelf"
#define JARSHELF_CLASSPATH_DESC "()[Lcc/squirreljme/jvm/mle/brackets/JarPackageBracket;"
#define JARSHELF_LIBRARIES_DESC "()[Lcc/squirreljme/jvm/mle/brackets/JarPackageBracket;"
#define JARSHELF_LIBRARYPATH_DESC "(Lcc/squirreljme/jvm/mle/brackets/JarPackageBracket;)Ljava/lang/String;"
#define JARSHELF_OPENRESOURCE_DESC "(Lcc/squirreljme/jvm/mle/brackets/JarPackageBracket;Ljava/lang/String;)Ljava/io/InputStream;"
JNIEXPORT jobject JNICALL Impl_mle_JarShelf_classPath(JNIEnv* env,
jclass classy)
{
return forwardCallStaticObject(env, JARSHELF_CLASSNAME,
"classPath", JARSHELF_CLASSPATH_DESC);
}
JNIEXPORT jobject JNICALL Impl_mle_JarShelf_libraries(JNIEnv* env,
jclass classy)
{
......@@ -41,6 +49,7 @@ JNIEXPORT jobject JNICALL Impl_mle_JarShelf_openResource(JNIEnv* env,
static const JNINativeMethod mleJarMethods[] =
{
{"classPath", JARSHELF_CLASSPATH_DESC, (void*)Impl_mle_JarShelf_classPath},
{"libraries", JARSHELF_LIBRARIES_DESC, (void*)Impl_mle_JarShelf_libraries},
{"libraryPath", JARSHELF_LIBRARYPATH_DESC, (void*)Impl_mle_JarShelf_libraryPath},
{"openResource", JARSHELF_OPENRESOURCE_DESC, (void*)Impl_mle_JarShelf_openResource},
......
......@@ -73,134 +73,6 @@ JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_atomicIncrement
JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_breakpoint
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfBoolean
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfBoolean
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfBooleanPointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfBooleanPointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfByte
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfByte
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfBytePointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfBytePointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfCharacter
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfCharacter
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfCharacterPointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfCharacterPointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfDouble
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfDouble
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfDoublePointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfDoublePointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfFloat
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfFloat
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfFloatPointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfFloatPointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfInteger
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfInteger
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfIntegerPointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfIntegerPointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfLong
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfLong
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfLongPointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfLongPointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfShort
* Signature: ()Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfShort
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: classInfoOfShortPointer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_classInfoOfShortPointer
(JNIEnv* env, jclass classy);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: doublePack
......@@ -809,70 +681,6 @@ JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_monitorOwnerSetAtomic__L
JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_monitorOwnerSetAtomic__Ljava_lang_Object_2Ljava_lang_Thread_2
(JNIEnv* env, jclass classy, jobject, jobject);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectGetClassInfo
* Signature: (J)Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_objectGetClassInfo__J
(JNIEnv* env, jclass classy, jlong);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectGetClassInfo
* Signature: (Ljava/lang/Object;)Lcc/squirreljme/jvm/ClassInfo;
*/
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_Assembly_objectGetClassInfo__Ljava_lang_Object_2
(JNIEnv* env, jclass classy, jobject);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectGetClassInfoPointer
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_objectGetClassInfoPointer__J
(JNIEnv* env, jclass classy, jlong);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectGetClassInfoPointer
* Signature: (Ljava/lang/Object;)J
*/
JNIEXPORT jlong JNICALL Java_cc_squirreljme_jvm_Assembly_objectGetClassInfoPointer__Ljava_lang_Object_2
(JNIEnv* env, jclass classy, jobject);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectSetClassInfo
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_objectSetClassInfo__JJ
(JNIEnv* env, jclass classy, jlong, jlong);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectSetClassInfo
* Signature: (Ljava/lang/Object;J)V
*/
JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_objectSetClassInfo__Ljava_lang_Object_2J
(JNIEnv* env, jclass classy, jobject, jlong);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectSetClassInfo
* Signature: (JLcc/squirreljme/jvm/ClassInfo;)V
*/
JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_objectSetClassInfo__JLcc_squirreljme_jvm_ClassInfo_2
(JNIEnv* env, jclass classy, jlong, jobject);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectSetClassInfo
* Signature: (Ljava/lang/Object;Lcc/squirreljme/jvm/ClassInfo;)V
*/
JNIEXPORT void JNICALL Java_cc_squirreljme_jvm_Assembly_objectSetClassInfo__Ljava_lang_Object_2Lcc_squirreljme_jvm_ClassInfo_2
(JNIEnv* env, jclass classy, jobject, jobject);
/*
* Class: cc_squirreljme_jvm_Assembly
* Method: objectToPointer
......
......@@ -30,13 +30,37 @@ import java.util.Objects;
*/
public final class EmulatedJarPackageShelf
{
/** Library path property. */
private static final String LIB_PATH_PROPERTY =
"squirreljme.hosted.libraries";
/** Cache of our own classpath. */
private static JarPackageBracket[] _CLASSPATH_CACHE;
/** Cache of loaded libraries. */
private static JarPackageBracket[] _LIB_CACHE;
/**
* Returns our classpath.
*
* @return Our classpath.
* @since 2021/06/24
*/
public static JarPackageBracket[] classPath()
{
// Use single cache for it, if available
JarPackageBracket[] rv = EmulatedJarPackageShelf._CLASSPATH_CACHE;
if (rv != null)
return rv.clone();
// Use the system property to know our true classpath
String paths = System.getProperty(EmulatedTaskShelf.RUN_CLASSPATH);
if (paths != null)
rv = EmulatedJarPackageShelf.__loadPaths(paths);
else
rv = new JarPackageBracket[0];
// Store cache for later usages
EmulatedJarPackageShelf._CLASSPATH_CACHE = rv;
return rv.clone();
}
/**
* Returns the libraries which are available to the virtual machine.
*
......@@ -53,36 +77,11 @@ public final class EmulatedJarPackageShelf
// For hosted VMs, the libraries are stored in a system property so
// that they can be accessed.
String paths = System.getProperty(
EmulatedJarPackageShelf.LIB_PATH_PROPERTY);
EmulatedTaskShelf.AVAILABLE_LIBRARIES);
if (paths != null)
{
List<JarPackageBracket> fill = new ArrayList<>();
for (int at = 0, next;; at = next + 1)
{
// Get the segment from this section
next = paths.indexOf(File.pathSeparatorChar, at + 1);
String segment = (next < 0 ? paths.substring(at) :
paths.substring(at, next));
Path segPath = Paths.get(segment);
// Are we filling a JAR or filling random file data?
VMClassLibrary vmLib;
if (JarClassLibrary.isJar(segment))
vmLib = new JarClassLibrary(segPath);
rv = EmulatedJarPackageShelf.__loadPaths(paths);
else
vmLib = new DataContainerLibrary(segPath);
// Wrap class library container
fill.add(new EmulatedJarPackageBracket(vmLib));
// Processing no more
if (next < 0)
break;
}
// Store them all
rv = fill.toArray(new JarPackageBracket[fill.size()]);
}
rv = new JarPackageBracket[0];
// Store cache for later usages
EmulatedJarPackageShelf._LIB_CACHE = rv;
......@@ -127,4 +126,41 @@ public final class EmulatedJarPackageShelf
return ((EmulatedJarPackageBracket)__jar).openResource(__rc);
}
/**
* Loads paths from the given JAR set.
*
* @param __paths The paths to load.
* @return Loaded JAR brackets for the given paths.
* @since 2021/06/24
*/
private static JarPackageBracket[] __loadPaths(String __paths)
{
List<JarPackageBracket> fill = new ArrayList<>();
for (int at = 0, next;; at = next + 1)
{
// Get the segment from this section
next = __paths.indexOf(File.pathSeparatorChar, at + 1);
String segment = (next < 0 ? __paths.substring(at) :
__paths.substring(at, next));
Path segPath = Paths.get(segment);
// Are we filling a JAR or filling random file data?
VMClassLibrary vmLib;
if (JarClassLibrary.isJar(segment))
vmLib = new JarClassLibrary(segPath);
else
vmLib = new DataContainerLibrary(segPath);
// Wrap class library container
fill.add(new EmulatedJarPackageBracket(vmLib));
// Processing no more
if (next < 0)
break;
}
// Store them all
return fill.toArray(new JarPackageBracket[fill.size()]);
}
}
......@@ -183,6 +183,9 @@ public final class EmulatedTaskShelf
// Use these arguments
builder.command(args);
// Debug
Debugging.debugNote("Forked CmdLine: %s", args);
// Alternative piping for standard output
switch (__stdOut)
{
......
......@@ -9,15 +9,6 @@
package cc.squirreljme.emulator;
import cc.squirreljme.emulator.fb.NativeFramebuffer;
import cc.squirreljme.jvm.SystemCallError;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.jvm.config.ConfigRomKey;
import cc.squirreljme.jvm.config.ConfigRomType;
import cc.squirreljme.jvm.mle.constants.LineEndingType;
import java.io.IOException;
import java.io.OutputStream;
/**
* This contains the implementation of some system calls in the event that the
* JNI emulation layer does not have a C-based implementation of a method.
......
......@@ -39,6 +39,8 @@ public final class NativeBinding
libFile = NativeBinding.__libFromResources();
// Debug
System.err.printf("Java Version: %s%n",
System.getProperty("java.version"));
System.err.printf("Java Over-Layer: Loading %s...%n", libFile);
// Try loading the library now
......
// -*- 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.emulator;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import org.testng.IAlterSuiteListener;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
/**
* Alters suite names.
*
* @since 2020/02/26
*/
public class SquirrelJMEAlterSuiteListener
implements IAlterSuiteListener
{
/** The service resource file. */
public static final String SERVICE_RESOURCE =
"META-INF/services/net.multiphasicapps.tac.TestInterface";
/**
* {@inheritDoc}
* @since 2020/02/26
*/
@Override
public void alter(List<XmlSuite> suites)
{
// Poke the native bindings class so it gets initializes and setup
new NativeBinding();
// Go through our test suites
for (XmlSuite suite : suites)
{
// Only adjust SquirrelJME suites
if (!"squirreljme".equals(suite.getName()))
continue;
// Get pre-existing test group
XmlTest test = null;
for (XmlTest sub : suite.getTests())
if ("tests".equals(sub.getName()))
{
test = sub;
break;
}
// Create one?
if (test == null)
{
test = new XmlTest();
test.setSuite(suite);
test.setName("tests");
suite.addTest(test);
}
// Add tests for every test class (each class has just one)
List<XmlClass> classies = new LinkedList<>();
for (String testClass : SquirrelJMEAlterSuiteListener
.findTestClasses())
try
{
XmlClass classy = new XmlClass();
// It needs to point to our class!
classy.setName(testClass);
classy.setClass(Class.forName(testClass));
// Use this test
classies.add(classy);
}
catch (ClassNotFoundException e)
{
// Ignore
}
// Use these classes
test.setClasses(classies);
}
}
/**
* Returns the base name for the class.
*
* @param __name The name of the class.
* @return The base name.
* @since 2020/02/26
*/
public static String baseClassName(String __name)
throws NullPointerException
{
if (__name == null)
throw new NullPointerException("No name specified.");
int ld = __name.lastIndexOf('.');
return (ld < 0 ? __name : __name.substring(ld + 1));
}
/**
* Returns the base package for the class.
*
* @param __name The name of the class.
* @return The base package.
* @since 2020/02/26
*/
public static String basePackage(String __name)
throws NullPointerException
{
if (__name == null)
throw new NullPointerException("No name specified.");
int ld = __name.lastIndexOf('.');
return (ld < 0 ? __name : __name.substring(0, ld));
}
/**
* Collects all of the test classes that are known about.
*
* @return The test classes.
* @since 2020/02/26
*/
public static Iterable<String> findTestClasses()
{
Collection<String> rv = new LinkedList<>();