Skip to content

Developer Notes

Istvan Novak edited this page Nov 11, 2020 · 2 revisions

Building Klive IDE

Klive IDE is a mono-repository that currently has two projects with their corresponding package.json files withing the packages folder:

  • klive-emu: The Klive Emulator. This package is an Electron shell application that implements the emulator.
  • klive-vsext: The VS Code Extension for Klive IDE. This package is an extension you can install in VS Code (version over 1.46.0).

There is a package.json file in the project's root folder, which uses lerna to handle the monorepo.

Install the Development Environment

Execute these commands:

git clone https://github.com/Dotneteer/kliveide.git
npm run bootstrap

Working with the Packages

Note: I know, the current build method is not a sophisticated solution, but it works. If you have some improvement for it, which works on Windows, Mac, and Linux, please contribute and create a PR accordingly.

klive-emu

When you work with the klive-emu package, you can open either the root project folder or the packages/klive-emu folder. These commands in the root package.json file are redirected to packages/klive-emu:

  • dev (npm run dev): Builds the Klive Emulator in development mode. This command watches for file changes (except the WebAssembly files) and rebuilds the klive-emu package when a change occurs.
  • spbuild (npm run spbuild): Builds the WebAssembly part of the emulator.
  • start (npm start): Starts the Klive Emulator

This is the method I use while developing the emulator:

  1. I open a new terminal pane in VS Code and execute npm run dev.
  2. In an additional terminal pane I execute npm start. Of course, I have to wait while the npm run dev command reaches the point when the initial compilation is done befor I can carry out npm start.
  3. As I change the source code of the emulator, the first process watches for changes and continuously recreates the executable package. Of course, when I want to try the changes, I have to terminate the second process and then execute npm start again.
  4. When I modify the WebAssembly code, I have to terminate the npm run dev process, too, as it does not watch for WebAssembly files.

Note: A few months ago, I used the chokidar package to reload the Emulator app automatically after source code changes, but it produced strange behavior on Mac, so I eliminated it.

If you do not like the two-terminal model, these are the commands to execute after every source code change to run the newest version:

npm run build:emu
npm start

The npm run build:emu command rebuilds the entire emulator (including the WebAssembly parts).

The Build Process of the Emulator

npm run build:emu carries out these steps:

  1. Uses the src/scripts/mergewat.js script to merge the separate .wat files within the src/native folder into a single file to run the WebAssembly compiler in the next step. The mergewat.js file uses src/scripts/wat.json file to list the .wat partitions to merge.
  2. With the wat2wasm tool, the build creates a single .wasm file that contains the WebAssembly binaries. The emulator loads that part in run time.
  3. The build executes Webpack to complete the build process.

WebAssembly Helpers

For performance reasons, the Klive Emulator uses native WebAssembly for the virtual machine core. Before that, I had an AssemblyScript implementation of that code that was about three times slower.

Native WebAssembly means that we need to write the code in WebAssembly Text format (`.wat). The WAT format is pretty poor, as it can handle only a single input file and lacks some common constructs like constant values to be replaced during compile time.

So the mergewat.js tool does a few other things besides appending the .wat source code files:

When the files are appended, it searches for WebAssembly remarks and parses them. It looks for constant declarations identifiers and values, like this:

;; $myConstant# = 1234

Here, $myConstant# is a constant name, 1234 is its value. The constant names should be valid WAT identifiers and end with #. The values can be decimal literals or hexadecimal literals with 0x prefix (for example, 0x12ac).

The mergewat.js tool replaces the constant names in the WAT file with the corresponding values. Look at this code snippet:

(i32.add (get_global $tacts) (i32.const $myConstant#))
;; ...
;; a few handred lines later:
;; $myConstant# = 1234

After mergewat.js runs, it results in this code line:

(i32.add (get_global $tacts) (i32.const 1234))

klive-vsext

This package is a VS Code extension. To develop it, open the packages/klive-vsext folder in a separate VS Code window. The source code of the extension is split into these parts:

  • Custom VS Code editors: this part of the source code (the src/custom-editors folder) is written with the Svelte framework and is compiled with Webpack.
  • Extension assets: this part of the source code is involved in the Webpack build (the assets folder)
  • VS Code extension components: these parts support the default VS Code extension build tasks.

When you modify only the VS Code extension components, you can immediately try the changes with the Run|Start Debugging and the Run|Run Without Debugging VS Code commands. However, if you modify the assets or any of the custom VS Code editors, you need to run npm run build in order Run|Start Debugging* and Run|Run Without Debugging work with the modified custom editors.