Table of Contents
In order to compile EduMIPS64, you need the Java JDK version 11 or above.
To build the user documentation, you'll need:
- Python 3
- Sphinx (http://www.sphinx-doc.org/) version 2.3.1 or above
- rst2pdf (for the PDF files) version 0.9.6 or above
You can install the Python dependencies using PIP:
$ pip3 install -r docs/requirements.txt
Gradle will download the following dependencies:
- GWT (experimental)
To generate an installable Windows MSI package (using the Gradle
msi task), you will need
JDK 14+ and the WiX toolkit.
This project uses GitHub Actions for continuous integration (https://github.com/EduMIPS64/edumips64/actions).
Main Gradle tasks
./gradlew assemble- (Java plugin) compile and assemble jar artifacts
./gradlew check- (Java plugin) run tests and compile the documentation
./gradlew run- (Application plugin) run the application
./gradlew war- (GWT plugin) compile the GWT-based web worker running the EduMIPS64 core
You may also find useful using the
--console=plain flag to better see what tasks
are being executed.
Individual tasks for building single documentation (PDF and HTML) and jar targets are available too: please read
build.gradle for the complete list.
Gradle builds the following jar artifacts:
edumips64-<version>.jar: GUI executable jar (includes JavaHelp and picocli)
Gradle is supported by all the main Java IDEs (e.g. IDEA, Eclipse, NetBeans).
For developers that don't want to recompile the help files when creating a JAR, the
noHelpJar Gradle task will produce
edumips64-<version>-nohelp.jar, which does
not include the compiled help files.
Visual Studio Code
If you want to work on EduMIPS64 with Visual Studio Code, you need to download the Java Extension Pack (see Java in Visual Studio Code).
To make it recognize the EduMIPS64 folder as a project, run
./gradlew eclipse to generate
Eclipse-style project files, which are readable by the VSCode plugins.
Working on the Web UI
An experimental web frontend, based on GWT and React, is being developed right now.
run inside a web worker. The code for the worker is in the
package; of course, building the worker also requires building most of the rest
of the EduMIPS64 core. The GWT configuration is in the
The GWT code runs as a Web Worker to enable concurrency between UI interaction and the execution of the simulation steps.
To compile it, run the
war task, which will produce the file
war gradle task wipes the
So if you re-build the worker, you need to re-build the rest of the web UI as well
to have a working local test environment (see next section).
The web UI itself is based on React, and it's compiled / assembled using the NPM and
webpack tools. The source code is in
Custom NPM scripts:
webpack -d(compile with debugging symbols)
webpack -p(compile without debugging symbols, minified, etc)
start: starts the webpack-dev-server with live reloading
build-dbg produce a
ui.js file in the
Source code structure
The source code structure follows the Gradle project layout conventions.
The main package for the simulator is
org.edumips64, therefore the Java code
src/main/java/org/edumips64, and contains 5 sub-packages, plus
the entry points.
Main.java is the code for the main Swing frontend entry point, while
contains an experimental CLI front-end.
clientpackage contains Java code for the Web UI.
corepackage contains all the core classes for the simulator, including important bits such as the CPU, the Memory, instructions and the Parser.
imgpackage contains a class to load images and the actual images used in the simulator.
uipackage contains the code for the Swing UI.
utilspackage contains miscellaneous code, including abstractions needed to decouple the core code from packages that are not available in the GWT JRE emulation (such as
We use the GitHub Flow
development workflow, which means that
master is always fully working
(the code can be built and all tests pass), and development is done in separate
named branches. The good state of
master is enforced by its protected
status, meaning that no commits can be pushed directly to
master and any
pull requests for
master have to pass the status checks (Github Actions building
the code and executing unit tests).
It is expected that all new features are implemented with good unit tests coverage.
There is a suite of end-to-end tests, but any significant change to core classes should ideally come with their own separate unit tests.
Unit tests are stored in the
src/test directory. The
subdirectory contains MIPS64 programs that are executed during unit test as a
form of end-to-end unit tests, whereas
java contains the actual Java code
that runs unit tests.
The main tests are contained in
EndToEndTests.java. This class contains unit
tests that run MIPS64 code (contained in
resources). One of the common
patterns in those tests is that, if something goes unexpectedly during the
execution of unit tests, the MIPS64 code executes a
BREAK instruction, which
will trigger a
BreakException in the Java code and make the test fail. Tests
CpuTests.java can also verify other behaviors, including forwarding and
correct working of the Dinero Tracefile generation logic.
Other types of test, e.g.,
MemoryTest.java, will test
other components in isolation.
To add a unit test, the first consideration is whether this test should be
writte in assembly or in Java. Tests in assembly should typically be put in
CpuTests.java, since it contains already boilerplate for executing and
verifying assembly programs. Tests which should not be written in assembly,
and therefore most likely exercise only one component, should pertain to other
classes, possibly even an entirely new class if required.
When writing new unit test classes, pay attention to the initialization code necessary to initialize the simulator. Look at other unit test classes to make sure your new class behaves as required.
The Swing UI code is explicitly excluded from code coverage reports because writing tests for it is quite difficult and might not be worth it since we might be migrating to a new shiny web-based frontend.
EduMIPS64 compiles under Windows, both natively (e.g., using PowerShell) and in WSL.
Mac OS X
The build works under Mac OS X (tested with Catalina 10.15.2, AdoptOpenJDK 11.0.7).
The only thing that might not work out of the box is downloading the Gradle GWT plugins, as the Maven repo uses Let's Encrypt as a certificate issuer, which is not trusted by default by the JDK.
Follow instructions here to import the Let's Encrypt root certificates in the JDK keystore.
Manual release checklist
Before doing a release, please do the following tasks. Over time, those should be automated, but before that is done those checks should be done manually.
- For each released JAR / MSI file:
- verify that the splash screen works
- verify that the version number, code name, build date and git ID are correct
- open one .s file (e.g.,
- run it
- open the help
- close the application
- verify the JAR size (should be < 3 MB)
- open the English manual and check the version
- open the Italian manual and check the version
- check the 'edge' snap and promote it to stable if it works (https://snapcraft.io/edumips64/releases, needs login)
Overriding instruction field values
Many instruction class contain static fields. This can be confusing and error-prone. If a concrete instruction
defines any fields that are defined in parent classes (such as, for example,
OPCODE_VALUE), it is important that
the constructor also overrides the value of the same attribute for the superclass, or some methods will not work properly.
This is clearly too convoluted and should be redesigned in a way that makes it impossible to make mistakes.