https://github.com/richardanaya/wasm-script
Compile WebAssembly in your HTML
https://github.com/richardanaya/wasm-script
compilers webassembly
Last synced: 7 months ago
JSON representation
Compile WebAssembly in your HTML
- Host: GitHub
- URL: https://github.com/richardanaya/wasm-script
- Owner: richardanaya
- License: mit
- Created: 2020-10-31T00:46:13.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2020-12-08T03:26:11.000Z (about 5 years ago)
- Last Synced: 2024-11-24T23:12:30.678Z (over 1 year ago)
- Topics: compilers, webassembly
- Language: JavaScript
- Homepage:
- Size: 390 KB
- Stars: 30
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# wasm-script
This is a library for bringing your WebAssembly compiler to the web.
# Vision
```html
extern int add(int a, int b){
return a + b;
}
// Compile as a module for accelerating javascript
const mathModule = await document.getElementById("math").compile();
console.log(mathModule.add(2,2));
```
Or run stand alone
```html
```
# Features
- [x] script for loading a WebAssembly module from a compiler
- [ ] ask to load dependent files by url
- [ ] cacheing
- [x] show compile errors in console
# CDN
```
https://cdn.jsdelivr.net/gh/richardanaya/wasm-script@latest/wasm-script.js
```
# Reference Implementation
A reference implementation compiler is in progress in Rust for the [`wasp`](https://github.com/wasplang/wasp) programming language ( a simple lisp-like syntax language ).
```html
pub fn secret(){
42
}
// top-level await doesn't exist yet, so we have to do it the lame way
(async function(){
const mathModule = await document.getElementById("math").compile();
document.body.innerHTML = mathModule.secret(1);
})();
```
See the demo [here](https://richardanaya.github.io/wasm-script/examples/demo.html)
What the compiler is doing is fairly simple:
```rust
use wasm_compiler::{process,log};
use wasp_core::{compiler, parser};
#[no_mangle]
pub fn compile(code_ptr: usize) -> usize {
process(code_ptr, |code| {
log("compiling the code below!!");
log(&code);
let app = parser::parse(code)?;
Ok(compiler::compile(app)?)
})
}
```
# Exposing Browser Functionality
Until we have DOM exposure in WebAssembly, we still are in a position we need to provide our own exposures to the browser's functionality. This library has some helper functions
for common memory structures.
```html
extern console_log(message)
pub fn main(){
console_log("hello world!")
}
// top-level await doesn't exist yet, so we have to do it the lame way
(async function(){
const mathModule = await document.getElementById("math").compile({
console_log: function(message_start) {
const message = WasmScript.getCString(mathModule.memory,message_start)
document.body.innerHTML += message;
}
});
mathModule.main();
})();
```
See the demo [here](https://richardanaya.github.io/wasm-script/examples/helloworld.html)
## Memory Helper API
* `WasmScript.getCString(mem,start)` - Returns a utf-8 string from position in memory that ends with a zero character.
* `WasmScript.getUint8ArrayFromMemory(mem,start)` - Returns a Uint8Array from position in memory, starting with a uint32 count followed by the elements.
# Building Your Own Compiler
Right now the current contract for building a compiler is very simple and can be implemented in any language that compiles to WebAssembly:
```rust
// external function to print a long takes a zero-character ending C string
extern void compiler_log(uint32 start_cstr)
// external function to print a error log and throw an exception takes a zero-character ending
// C string ( this function does not return )
extern void compiler_error(uint32 start_cstr)
// allocate some bytes of size
uint32 malloc(uint32 size)
// compile a code by passing in the start of the code in memory (created using malloc above).
// and get back a list of bytes (the length as u32, followed by the data)
uint32 compile(uint32 code_str)
```