The goal of JOSS (JSON Operating System Schema) is to create a protocol for interacting with a UNIX-like environment via the host interface of web assembly using JSON.
Web assembly is going down the route of running not just in the browser but also outside of the browser. It needs a common way of communicating with the outside world. Traditionally technologies have utilized C style structs for communicating data across boundries. JOSS is a standard that utilizes JSON instead. There are several reason for this approach.
Not every programming language has a strong capability to do binary structs. By using JSON we reduce the requirements of interacting with a JOSS system down to JSON parsing/encoding and C strings.
Human readability helps debugging and making introspection into how systems are behaving way easier.
It's one of the most known structured formats out there and has very strong library support already.
Let's face it, performance of interacting with operating system isn't always the most important aspect of our program. When it is though, JOSS does not limit the ability to use alternative performant interactions. Binary structures could be percieved as an overeager optimization in many scenarios.
Most of the web already understands JSON, imagine you are writing an interface to a JOSS system in a web browser that communicates to a server which represents your system. This situation more easily accomplished by communication with JSON over a http or web socket.
Because JSON is a less rigid structure than a binary format. Error handling is easier and more expressive to implement into the spec.
Because web assembly lacks an easy way to return multiple outputs, we are forced to resort to a structured format of some type. Even with the use of multiple outputs, representing return objects that are very nested or have arrays may be problematic. JSON has few if none of these complexities (asside from memory allocation) and works with the web assembly spec as it is now.
JOSS takes inspiration from UNIX, Plan 9, and Redox system calls:
- set_current_directory
- get_process_id
- file_open
- file_close
- file_read
- file_write
- file_get_path
- file_rename
- file_get_metadata
- file_link
- file_unlink
- file_set_offset
- exit
- . (the current directory file descriptor)
- .. (the parent directory file descriptor)
- /dev/stdin (file_descriptor:0)
- /dev/stdout (file_descriptor:1)
- /dev/stderr (file_descriptor:2)
- /dev/clock (file_descriptor:3)
- /proc/[id]/args
{
"operation":"get_process_id"
}
> { "process_id": 123 }
{
"operation":"file_open",
"mode":["read"],
"path":"/proc/123/args"
}
> { "file_descriptor": 5 }
{
"operation":"file_read",
"file_descriptor": 5
}
> { "text":"[\"vim\",\"foo.txt\"]" }
{
"operation":"file_open",
"mode":["write"],
"path":"/hello.txt"
}
> { "file_descriptor": 5 }
{
"operation":"write_to_file",
"file_descriptor":5,
"text":"hello world"
}
> {}
{
"operation":"write_to_file",
"file_descriptor":5,
"base64":"basbfrasfs="
}
> {}
This application echo
will simply write to the console log what command line arguments it receives. This app has various small helper libraries:
serde
- for getting json in and outputmalloc
- a small package exposing a function calledmalloc
to let data get into your web assembly modulejoss
- a simple rust wrapper for sending JOSS operations to the host
#[macro_use]
extern crate serde_derive;
extern crate malloc;
use joss;
use serde_json::{from_str, json};
#[no_mangle]
fn main() {
// write to stdout
let output_json = json!({
"operation": "file_write",
"file_descriptor": 1,
"text":"Hello World!"
});
joss::syscall(output_json.to_string());
}