JavaScript engine implemented in Rust, now aiming at ES5.
Big thanks to boa.
On this page, you can try rapidus compiled into WASM on your browser. How amazing, isn't it?
The compiled rapidus on the above page is some commits behind this branch.
Run the command below and follow the onscreen instructions.
curl https://sh.rustup.rs -sSf | sh
rustup override set nightly
# e.g. Ubuntu or Debian
apt-get install llvm-6.0
cargo test
ln -sf /usr/bin/llvm-config-6.0 /usr/bin/llvm-config
cargo run --release
cargo run --release examples/XXX.js
$ cargo run
> function fact(n) {
... if (n < 2) { <- recognize multilined input
... return n
... } else {
... return n * fact(n-1)
... }
... } <- recognize the end of input
undefined
> fact(10)
3628800
Debug mode (tracing bytecode execution)
use --trace option.
$ cargo run -- --trace
> function fibo(x) { if (x<2) return 1; return fibo(x-1)+fibo(x-2)}
00020m 00000 Return <empty>
undefined
> fibo(3)
00009m 00000 PushInt8 3 <empty>
00015m 00002 GetValue 'fibo' 3.0
00066m 00007 Call 1 Function
--> call function
module_id:0 func_id:0
00007m 00000 GetValue 'x' <empty>
00001m 00005 PushInt8 2 3.0
00013m 00007 Lt 2.0
...
00001m 00007 Lt 2.0
00000m 00008 JmpIfFalse 00016 true
00000m 00013 PushInt8 1 <empty>
00167m 00015 Return 1.0
<-- return value(1.0)
module_id:0 func_id:2
00001m 00052 Add 1.0
00044m 00053 Return 3.0
<-- return value(3.0)
module_id:0 func_id:0
00000m 00012 Return 3.0
3
>
| | | |
| | | \- value at the top of exec stack
| | \-------------------------- instruction
| \-------------------------------- program counter
\-------------------------------------- execution time per inst. (in microsecs)
I don't know.
brew
. You should use macports or docker instead.THIS FEATURE IS EXPERIMENTAL
$ cargo new hello --lib
$ ls
rapidus hello
Cargo.toml
$ cd hello
$ <YOUR EDITOR> Cargo.toml
# Add the followings to Cargo.toml
[dependencies]
rapidus = { path = "../rapidus" }
# other dependencies if you want...
[lib]
name = "hello"
crate_type = ["cdylib"] # try 'dylib' if it doesn't work.
src/lib.rs
$ <YOUR EDITOR> src/lib.rs
// src/lib.rs
#[macro_use]
extern crate rapidus;
use rapidus::{
gc,
vm::{callobj::CallObject, error::RuntimeError, value::*, vm::VM},
};
#[no_mangle]
fn initialize(vm: &mut VM, _: &Vec<Value>, _: CallObjectRef) -> Result<(), RuntimeError> {
// make_object!() is useful
let module_exports = make_object!(
greet: Value::default_builtin_function(greet),
message: Value::String("hello".to_string())
);
vm.set_return_value(module_exports); // We have to return module.exports
Ok(())
}
#[no_mangle]
fn greet(vm: &mut VM, _: &Vec<Value>, _: CallObjectRef) -> Result<(), RuntimeError> {
println!("Hello World from Rust DLL!");
vm.set_return_value(Value::Undefined); // Remember to return a value you want
Ok(())
}
$ cargo build # --release as necessary
$ cp ./target/debug/libhello.(so|dll|dylib) ../rapidus
$ cd ../rapidus
$ ls
libhello.(so|dll|dylib) etc...
$ cargo run
> var mod = require('hello')
> mod.greet()
Hello World from Rust DLL!
> mod.message
'hello'