cppbolt 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -2
- package/package.json +12 -4
- package/wasm/cppbolt.wasm +0 -0
package/README.md
CHANGED
|
@@ -1,3 +1,126 @@
|
|
|
1
|
-
#
|
|
1
|
+
# cppbolt
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
cppbolt compiles a subset of C++17 directly to WebAssembly without LLVM, Emscripten, or a native toolchain. This package contains the compiler built for `wasm32-unknown-unknown`; it exposes a C ABI and has no imports, so you can instantiate it with an empty import object in Node.js, browsers, or Web Workers.
|
|
4
|
+
|
|
5
|
+
The package contains the raw WebAssembly module with no JavaScript wrapper or CLI. You call the exports directly.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install cppbolt
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import { readFile } from "node:fs/promises";
|
|
17
|
+
import { createRequire } from "node:module";
|
|
18
|
+
|
|
19
|
+
const require = createRequire(import.meta.url);
|
|
20
|
+
const wasmPath = require.resolve("cppbolt/wasm/cppbolt.wasm");
|
|
21
|
+
const { instance } = await WebAssembly.instantiate(await readFile(wasmPath), {});
|
|
22
|
+
const compiler = instance.exports;
|
|
23
|
+
|
|
24
|
+
function compile(source) {
|
|
25
|
+
const input = new TextEncoder().encode(source);
|
|
26
|
+
const inputPtr = compiler.alloc_buffer(input.length);
|
|
27
|
+
new Uint8Array(compiler.memory.buffer, inputPtr, input.length).set(input);
|
|
28
|
+
|
|
29
|
+
const resultPtr = compiler.compile_wasm(inputPtr, input.length);
|
|
30
|
+
compiler.dealloc_buffer(inputPtr, input.length);
|
|
31
|
+
|
|
32
|
+
if (resultPtr === 0) {
|
|
33
|
+
const length = compiler.get_error_len();
|
|
34
|
+
const bytes = new Uint8Array(compiler.memory.buffer, compiler.get_error_ptr(), length);
|
|
35
|
+
throw new Error(new TextDecoder().decode(bytes));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const length = compiler.get_result_len();
|
|
39
|
+
const output = new Uint8Array(compiler.memory.buffer, resultPtr, length).slice();
|
|
40
|
+
compiler.free_result(resultPtr, length);
|
|
41
|
+
return output;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const wasm = compile(`
|
|
45
|
+
#include <iostream>
|
|
46
|
+
|
|
47
|
+
int main() {
|
|
48
|
+
std::cout << "Hello from WebAssembly C++!" << std::endl;
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
`);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`wasm` is a complete WebAssembly module.
|
|
55
|
+
|
|
56
|
+
### Browser
|
|
57
|
+
|
|
58
|
+
Serve `cppbolt.wasm` from your site, then load it:
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<script type="module">
|
|
62
|
+
const response = await fetch("/wasm/cppbolt.wasm");
|
|
63
|
+
const { instance } = await WebAssembly.instantiateStreaming(response, {});
|
|
64
|
+
const compiler = instance.exports;
|
|
65
|
+
</script>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`instantiateStreaming` needs the server to send `Content-Type: application/wasm`; otherwise use `WebAssembly.instantiate(await response.arrayBuffer(), {})`. The compiler ABI interaction inside the `compile` function can be reused in browsers. Replace the Node.js-specific WASM loading code with the browser loading example above.
|
|
69
|
+
|
|
70
|
+
## Compiler API
|
|
71
|
+
|
|
72
|
+
Pointers are 32-bit offsets into the module's exported `memory`.
|
|
73
|
+
|
|
74
|
+
| Export | Signature | Description |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `alloc_buffer` | `(size) -> ptr` | Allocates an uninitialized input buffer. |
|
|
77
|
+
| `dealloc_buffer` | `(ptr, size) -> void` | Releases an input buffer with the size passed to `alloc_buffer`. |
|
|
78
|
+
| `compile_wasm` | `(ptr, len) -> ptr` | Compiles UTF-8 source. Returns a pointer to the emitted module, or `0` on error. |
|
|
79
|
+
| `get_result_len` | `() -> len` | Returns the byte length of the result from the most recent `compile_wasm` call, or `0` if that call failed. |
|
|
80
|
+
| `free_result` | `(ptr, len) -> void` | Releases a result buffer returned by `compile_wasm`. |
|
|
81
|
+
| `get_error_ptr` | `() -> ptr` | Returns the address of the static error buffer. |
|
|
82
|
+
| `get_error_len` | `() -> len` | Returns the byte length of the diagnostic from the most recent failed `compile_wasm` call, or `0` if it succeeded. |
|
|
83
|
+
|
|
84
|
+
Ownership and lifetime rules:
|
|
85
|
+
|
|
86
|
+
- `compile_wasm` does not take ownership of the input buffer. Free it with `dealloc_buffer` after compiling.
|
|
87
|
+
- Call `get_result_len` before starting another compilation. Copy the bytes out, then call `free_result` once with that length.
|
|
88
|
+
- The error buffer is static storage owned by the compiler. The message stays valid until the next compilation and must not be freed. Messages are truncated to 4096 bytes.
|
|
89
|
+
- Linear memory growth can invalidate existing JavaScript memory views. Recreate `Uint8Array` and other typed-array views after calls that may grow memory. Numeric pointers remain offsets into linear memory.
|
|
90
|
+
|
|
91
|
+
Diagnostics use the format `<file>:line:column: error: message`. The ABI does not accept a filename, so the main source is reported as `<input>`; errors inside embedded headers use the header's name.
|
|
92
|
+
|
|
93
|
+
## Language coverage
|
|
94
|
+
|
|
95
|
+
cppbolt supports scalar types, pointers, arrays, functions, classes, single inheritance, virtual functions, operator overloading, lambdas, range-based `for`, and the preprocessor, along with an embedded mini standard library (`<iostream>`, `<string>`, `<cstdio>`, `<cmath>`, `<iomanip>`, and related headers).
|
|
96
|
+
|
|
97
|
+
Templates, standard containers and algorithms, exceptions, RTTI, and multiple or virtual inheritance are not supported.
|
|
98
|
+
|
|
99
|
+
Only the embedded headers can be included. The Wasm build has no filesystem access, so `#include` of any other file cannot be resolved.
|
|
100
|
+
|
|
101
|
+
See the [supported C++ subset](https://ajtimepyro.is-a.dev/cppbolt/book/user/supported-cpp.html) and [diagnostics catalog](https://ajtimepyro.is-a.dev/cppbolt/book/user/errors.html) for the full feature matrix and error list.
|
|
102
|
+
|
|
103
|
+
## Running compiled modules
|
|
104
|
+
|
|
105
|
+
Emitted modules are WebAssembly binaries that import standard I/O functions from an `env` namespace. Every emitted module imports all five functions:
|
|
106
|
+
|
|
107
|
+
| Import | Signature | Purpose |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `env.print_char` | `(i32) -> void` | Write one character byte to stdout. |
|
|
110
|
+
| `env.print_int` | `(i64, i32, i32, i32, i32) -> i32` | Format and write an integer. Returns the character count. |
|
|
111
|
+
| `env.print_double` | `(f64, i32, i32, i32, i32) -> i32` | Format and write a double. Returns the character count. |
|
|
112
|
+
| `env.read_char` | `() -> i32` | Read one character byte from stdin, or `-1` at end of input. |
|
|
113
|
+
| `env.exit` | `(i32) -> void` | Terminate with the given status code. |
|
|
114
|
+
|
|
115
|
+
Emitted modules export `memory`, `__stack_pointer`, and `__heap_base`, plus `main` if the program defines it. The compiler gives them a 256 MiB maximum linear memory, raised only when static data requires more.
|
|
116
|
+
|
|
117
|
+
The package does not include a host runtime. The repository's [`web/host.js`](https://github.com/AJTimePyro/cppbolt/blob/main/web/host.js) provides a reference implementation for Node.js and browsers. It handles the integer and floating-point formatting flags.
|
|
118
|
+
|
|
119
|
+
## Notes
|
|
120
|
+
|
|
121
|
+
- The compiler ABI is single-threaded and stores result state in one slot. Serialize calls and use one instance per worker.
|
|
122
|
+
- Compilation is synchronous. In a browser, run it in a Web Worker to keep the UI responsive.
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
Apache-2.0. See the [LICENSE](https://github.com/AJTimePyro/cppbolt/blob/main/LICENSE) file.
|
package/package.json
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cppbolt",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A C++ compiler targeting WebAssembly",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/AJTimePyro/cppbolt.git"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"wasm/cppbolt.wasm",
|
|
12
|
+
"README.md"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
Binary file
|