{"id":13830756,"url":"https://github.com/rsms/sol","last_synced_at":"2025-04-06T12:08:42.318Z","repository":{"id":5011663,"uuid":"6170136","full_name":"rsms/sol","owner":"rsms","description":"A sunny little virtual machine","archived":false,"fork":false,"pushed_at":"2015-07-15T17:32:41.000Z","size":719,"stargazers_count":524,"open_issues_count":1,"forks_count":40,"subscribers_count":39,"default_branch":"master","last_synced_at":"2025-03-30T10:09:06.867Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://rsms.me/2012/10/14/sol-a-sunny-little-virtual-machine.html","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rsms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-10-11T07:32:19.000Z","updated_at":"2025-02-22T03:01:10.000Z","dependencies_parsed_at":"2022-08-26T02:51:18.617Z","dependency_job_id":null,"html_url":"https://github.com/rsms/sol","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Fsol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Fsol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Fsol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Fsol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rsms","download_url":"https://codeload.github.com/rsms/sol/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247478323,"owners_count":20945266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T10:01:07.654Z","updated_at":"2025-04-06T12:08:42.297Z","avatar_url":"https://github.com/rsms.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# Sol\n\nA sunny little programming language on a register-based virtual machine.\n\n\n## VM design\n\nEach scheduler has one run queue in which tasks are queued for execution\n\n    VM\n    └ Scheduler (per OS thread)\n       ├ RunQueue\n       │ └ Task\n       │    ├ next → Task...\n       │    ├ super_task → Task...\n       │    ├ ActivationRecord\n       │    │ ├ next → ActivationRecord...\n       │    │ └ Function\n       │    │    ├ Constants\n       │    │    └ Instructions\n       │    ├ ProgramCounter\n       │    ├ Registry\n       │    ├ MessageInbox\n       │    └ WaitingForWatcher\n       └ WaitQueue\n          └ Task...\n\n      (Task migration)\n\nWhen more than one scheduler is running, tasks might migrate from one scheduler\nto another. For a more in-depth discussion about the design, see [\"Sol — a sunny little virtual machine\"](http://rsms.me/2012/10/14/sol-a-sunny-little-virtual-machine.html).\n\n## Examples\n\nThe examples below are expressed in a simplified assembly language that is almost 1:1 with the C API code for defining these programs programatically and thus the assembly language itself should be considered irrelevant beyond explaining the instructions executed.\n\n- In the output, lines like these: `[vm] ______________ ...` denote whent he scheduler regains control after running a task and the task either returned or yielded. This is one \"execution iteration\". When running multiple tasks, you will usually see tasks interleved in round-robin order between these \"execution iteration\" marker lines.\n\n- In the output, lines starting with \"...\" are comments and/or simplifications and not part of the actual output.\n\n- In assembly comments (\"; ...\"), `R(x)` means \"Register x\", `RK(x)` means \"Register x if x is less than 256 else Constant (x-255)\", `K(x)` means \"Constant x\".\n\n- In assembly comments (\"; ...\"), `PC` signifies the \"program counter\" which is sort of a cursor to the instructions of a program. It is incremented by one for each instruction executed. Some instructions will further modify this counter, like for instance the `JUMP` instruction.\n\n### Example 1: while x \u003e 0 yield ...\n\nWhile the variable x is greater than zero, decrement `x` by one and yield to the\nscheduler, letting other tasks run. Eventually return.\n\n```py\ndef main():\n  x = 5\n  while (x \u003e 0):\n    x = x - 1\n    yield\n  return\n```\n\nAssembly:\n\n```asm\ndefine main 0\n  CONST 5           ; K(0) = 5\n  CONST 0           ; K(1) = 0\n  CONST 1           ; K(2) = 1\n  entry:\n  LOADK  0  0       ; R(0) = K(0)\n  LE     0  0  256  ; (0 == RK(k+1) \u003c RK(0)) ? continue else PC++\n  JUMP   3          ; PC += 3 to RETURN\n  SUB    0  0  257  ; R(0) = R(0) - RK(k+1)\n  YIELD  0  0  0    ; yield A=type=sched\n  JUMP   -5         ; PC -= 5 to LE\n  RETURN 0  0       ; return\n```\n\nOutput when running in debug mode:\n\n    $ build/debug/bin/sol\n    Sol 0.1.0 x64\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 0          LOADK   AB:    0,   0\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 3          SUB     ABC:   0,   0, 257\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 4          YIELD   ABC:   0,   0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 5          JUMP    Bss:       -5\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 3          SUB     ABC:   0,   0, 257\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 4          YIELD   ABC:   0,   0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    ...three more execution iterations identical to the above block...\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 5          JUMP    Bss:       -5\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 2          JUMP    Bss:        3\n    [vm] 0x7fdf28c03c00 0x7fdf28c000e0 6          RETURN  AB:    0,   0\n    Scheduler runloop exited.\n\n### Example 2: Function calls and timers\n\nThis program uses two functions. The entry point is the `main` function which simply\ncalls the `kitten` function with one argument '500'. The `kitten` function \"sleeps\" for\nthe number of milliseconds passed to it (as the first argument.) The `kitten` function\nthen returns the number \"123\" to the caller—the `main` function—which dumps register values and\nfinally returns, causing the task to exit and subsequently the scheduler and the VM too to exit.\n\nAssembly:\n\n```asm\ndefine kitten 1     ; Arguments: (R(0)=sleep_ms)\n  CONST  123        ; K(0) = 123\n  entry:\n  YIELD  1  0  0    ; yield A=type=timer, RK(B)=R(0)=arg0\n  LOADK  0  0       ; R(0) = K(0) = 123\n  RETURN 0  1       ; return R(0)..R(0) = R(0) = 123\n\ndefine main 0       ; Arguments: ()\n  CONST  @kitten    ; K(0) = \u003cfunc kitten\u003e\n  CONST  500        ; K(1) = 500\n  entry:\n  LOADK  0  0       ; R(0) = K(0) = the kitten function\n  LOADK  1  1       ; R(1) = K(1) = 500\n  CALL   0  1  1    ; R(0)..R(0) = R(0)(R(1)..R(1)) = a(R(1))\n  DBGREG 0  1  0    ; VM debug function that dumps register values\n  RETURN 0  0       ; return\n```\n\nOutput when running in debug mode:\n\n    $ time build/debug/bin/sol\n    Sol 0.1.0 x64\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 0          LOADK   AB:    0,   0\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 1          LOADK   AB:    1,   1\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 2          CALL    ABC:   0,   1,   1\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc000e0 1          YIELD   ABC:   1,   0,   0\n    D Timer scheduled to trigger after 500.000000 ms (sched.c:81)\n    # ...time passes and in this case the scheduler is idling...\n    D Timer triggered -- scheduling task (sched.c:57)\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc000e0 2          LOADK   AB:    0,   0\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc000e0 3          RETURN  AB:    0,   1\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 3          DBGREG \n    D [vm] R(0) = 123.000000 (sched_exec.h:214)\n    D [vm] R(1) = 500.000000 (sched_exec.h:215)\n    D [vm] R(0) = 123.000000 (sched_exec.h:216)\n    [vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 4          RETURN  AB:    0,   0\n    Scheduler runloop exited.\n\n    real  0m0.504s\n    user  0m0.001s\n    sys   0m0.001s\n\n### Example 3: Multitasking\n\nHere we run three tasks, each running the program in *Example 1*:\n\n    $ build/debug/bin/sol\n    Sol 0.1.0 x64\n    [sched 0x7fc219403930] run queue:\n      [task 0x7fc219403c00] -\u003e [task 0x7fc219403cd0] -\u003e [task 0x7fc219403da0]\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fc219403c00 0x7fc2194000e0 0          LOADK   AB:    0,   0\n    [vm] 0x7fc219403c00 0x7fc2194000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fc219403c00 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257\n    [vm] 0x7fc219403c00 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 0          LOADK   AB:    0,   0\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fc219403da0 0x7fc2194000e0 0          LOADK   AB:    0,   0\n    [vm] 0x7fc219403da0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fc219403da0 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257\n    [vm] 0x7fc219403da0 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fc219403c00 0x7fc2194000e0 5          JUMP    Bss:       -5\n    [vm] 0x7fc219403c00 0x7fc2194000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fc219403c00 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257\n    [vm] 0x7fc219403c00 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    ...The above block of instruction is repeated three times in interleved\n       round-robin order for each task. Then:\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fc219403c00 0x7fc2194000e0 5          JUMP    Bss:       -5\n    [vm] 0x7fc219403c00 0x7fc2194000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fc219403c00 0x7fc2194000e0 2          JUMP    Bss:        3\n    [vm] 0x7fc219403c00 0x7fc2194000e0 6          RETURN  AB:    0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 5          JUMP    Bss:       -5\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 2          JUMP    Bss:        3\n    [vm] 0x7fc219403cd0 0x7fc2194000e0 6          RETURN  AB:    0,   0\n    [vm] ______________ ______________ __________ _______ ____ ______________\n    [vm] Task           Function       PC         Op      Values\n    [vm] 0x7fc219403da0 0x7fc2194000e0 5          JUMP    Bss:       -5\n    [vm] 0x7fc219403da0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256\n    [vm] 0x7fc219403da0 0x7fc2194000e0 2          JUMP    Bss:        3\n    [vm] 0x7fc219403da0 0x7fc2194000e0 6          RETURN  AB:    0,   0\n    Scheduler runloop exited.\n\n## Building\n\nInitial configuration\n\n    deps/libev-configure.sh\n\nBuild Sol and run tests (when in the same directory as this README file):\n\n    make\n\nBuild Sol in debug mode\n\n    make DEBUG=1 sol\n\nRun the debug version of Sol\n\n    ./build/debug/bin/sol\n\nBuild and run tests (potentially building Sol too):\n\n    make test\n\n### Build targets\n\n- (default) — Alias for \"sol test\"\n- `sol` — Build Sol\n- `test` — Build and run all unit tests\n- `clean` — Clean tests and clean the target type for sol (debug or not). Note that you need to pass the `DEBUG=1` flag to `make clean` to cause cleaning of debug builds. To remove everything that has been generated, simply `rm -rf ./build`.\n\nSol specific targets (i.e. for `make -C ./sol`):\n\n- `llvm_ir` — Compile all source files to LLVM IR assembly, placed in `\u003cBUILD_PREFIX\u003e/debug/sol-asm/\u003cname\u003e.ll`\n- `asm` — Compile all source files to target assembly, placed in `\u003cBUILD_PREFIX\u003e/debug/sol-asm/\u003cname\u003e.s`\n\n### Build flags\n\nSpecial flags that can be passed to make (e.g. `make FLAG=VALUE ...`):\n\n- `DEBUG=1|0` — When set to \"1\", build without optimizations, with debug symbols, with debug logging and with assertions. Defaults to \"0\", which causes building of \"release\" products (optimizations enabled, no debug logging and no assertions).\n\n- `TARGET_ARCH=NAME` — Set the architecture to build for. Valid values for `NAME` depends on the compiler. Defaults to the host architecture (as reported by `uname -m`). For instance, to build an IA32 product on a x64 system: `make TARGET_ARCH=i386`.\n\n- `BUILD_PREFIX` — Base directory for products. Defaults to `\u003cBASE_BUILD_PREFIX\u003e/\u003cDEBUG ? debug : release\u003e`.\n\n- `BASE_BUILD_PREFIX` — Base directory for tests and products. Defaults to `./build`.\n\n- `TESTS_BUILD_PREFIX` — Base directory for generated tests. Defaults to `\u003cBASE_BUILD_PREFIX\u003e/test`.\n\n# MIT License\n\nCopyright (c) 2012 Rasmus Andersson \u003chttp://rsms.me/\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsms%2Fsol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frsms%2Fsol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsms%2Fsol/lists"}