Basic WebAssembly support with minimal Javascript API #615. Currently 6/12 crypto functions supported. Tested in browser with all default features disabled.
This commit is contained in:
20
Cargo.toml
20
Cargo.toml
@@ -12,14 +12,18 @@ categories = ["command-line-utilities"]
|
|||||||
build = "build/main.rs"
|
build = "build/main.rs"
|
||||||
rust-version = "1.70"
|
rust-version = "1.70"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ffi", "repl", "hostname", "tls", "http"]
|
default = ["ffi", "repl", "hostname", "tls", "http", "crypto-full"]
|
||||||
ffi = ["dep:libffi"]
|
ffi = ["dep:libffi"]
|
||||||
repl = ["dep:crossterm", "dep:ctrlc", "dep:rustyline"]
|
repl = ["dep:crossterm", "dep:ctrlc", "dep:rustyline"]
|
||||||
hostname = ["dep:hostname"]
|
hostname = ["dep:hostname"]
|
||||||
tls = ["dep:native-tls"]
|
tls = ["dep:native-tls"]
|
||||||
http = ["dep:hyper", "dep:reqwest"]
|
http = ["dep:hyper", "dep:reqwest"]
|
||||||
rust_beta_channel = []
|
rust_beta_channel = []
|
||||||
|
crypto-full = []
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
@@ -80,7 +84,19 @@ tokio = { version = "1.28.2", features = ["full"] }
|
|||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
getrandom = { version = "0.2.10", features = ["js"] }
|
getrandom = { version = "0.2.10", features = ["js"] }
|
||||||
tokio = { version = "1.28.2", features = ["sync", "macros", "io-util", "rt", "time"] }
|
tokio = { version = "1.28.2", features = ["sync", "macros", "io-util", "rt"] }
|
||||||
|
|
||||||
|
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
|
||||||
|
console_error_panic_hook = "0.1"
|
||||||
|
console_log = "1.0"
|
||||||
|
wasm-bindgen = "0.2.87"
|
||||||
|
wasm-bindgen-futures = "0.4"
|
||||||
|
serde-wasm-bindgen = "0.5"
|
||||||
|
web-sys = { version = "0.3", features = [
|
||||||
|
"Document",
|
||||||
|
"Window",
|
||||||
|
"Element",
|
||||||
|
]}
|
||||||
|
|
||||||
[target.'cfg(target_os = "wasi")'.dependencies]
|
[target.'cfg(target_os = "wasi")'.dependencies]
|
||||||
ring-wasi = { version = "0.16.25" }
|
ring-wasi = { version = "0.16.25" }
|
||||||
|
|||||||
71
README.md
71
README.md
@@ -152,6 +152,77 @@ It will generate a very basic MSI file which installs the main executable and a
|
|||||||
|
|
||||||
Scryer Prolog must be built with **Rust 1.63 and up**.
|
Scryer Prolog must be built with **Rust 1.63 and up**.
|
||||||
|
|
||||||
|
### Building WebAssembly
|
||||||
|
|
||||||
|
Scryer Prolog has basic WebAssembly support. You can follow `wasm-pack`'s [official instructions](https://rustwasm.github.io/docs/wasm-pack/quickstart.html) to install `wasm-pack` and build it in any way you like.
|
||||||
|
|
||||||
|
However, none of the [default features](https://doc.rust-lang.org/cargo/reference/features.html#the-default-feature) are currently supported. The preferred way of disabling them is passing [extra options](https://rustwasm.github.io/wasm-pack/book/commands/build.html#extra-options) to `wasm-pack`.
|
||||||
|
|
||||||
|
For example, if you want a minimal working package without using any bundler like `webpack`, you can do this:
|
||||||
|
```
|
||||||
|
wasm-pack build --target web -- --no-default-features
|
||||||
|
```
|
||||||
|
Then a `pkg` directory will be created, containing everything you need for a webapp. You can test whether the package is successfully built by creating an html file, adapted from `wasm-bindgen`'s [official example](https://rustwasm.github.io/wasm-bindgen/examples/without-a-bundler.html) like this:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Scryer Prolog - Sudoku Solver Example</title>
|
||||||
|
<script type="module">
|
||||||
|
import init, { eval_code } from './pkg/scryer_prolog.js';
|
||||||
|
|
||||||
|
const run = async () => {
|
||||||
|
await init("./pkg/scryer_prolog_bg.wasm");
|
||||||
|
let code = `
|
||||||
|
:- use_module(library(format)).
|
||||||
|
:- use_module(library(clpz)).
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
|
||||||
|
sudoku(Rows) :-
|
||||||
|
length(Rows, 9), maplist(same_length(Rows), Rows),
|
||||||
|
append(Rows, Vs), Vs ins 1..9,
|
||||||
|
maplist(all_distinct, Rows),
|
||||||
|
transpose(Rows, Columns),
|
||||||
|
maplist(all_distinct, Columns),
|
||||||
|
Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is],
|
||||||
|
blocks(As, Bs, Cs),
|
||||||
|
blocks(Ds, Es, Fs),
|
||||||
|
blocks(Gs, Hs, Is).
|
||||||
|
|
||||||
|
blocks([], [], []).
|
||||||
|
blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :-
|
||||||
|
all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]),
|
||||||
|
blocks(Ns1, Ns2, Ns3).
|
||||||
|
|
||||||
|
problem(1, [[_,_,_,_,_,_,_,_,_],
|
||||||
|
[_,_,_,_,_,3,_,8,5],
|
||||||
|
[_,_,1,_,2,_,_,_,_],
|
||||||
|
[_,_,_,5,_,7,_,_,_],
|
||||||
|
[_,_,4,_,_,_,1,_,_],
|
||||||
|
[_,9,_,_,_,_,_,_,_],
|
||||||
|
[5,_,_,_,_,_,_,7,3],
|
||||||
|
[_,_,2,_,1,_,_,_,_],
|
||||||
|
[_,_,_,_,4,_,_,_,9]]).
|
||||||
|
|
||||||
|
main :-
|
||||||
|
problem(1, Rows), sudoku(Rows), maplist(portray_clause, Rows).
|
||||||
|
|
||||||
|
:- initialization(main).
|
||||||
|
`;
|
||||||
|
const result = eval_code(code);
|
||||||
|
document.write(`<p>Sudoku solver returns:</p><pre>${result}</pre>`);
|
||||||
|
}
|
||||||
|
run();
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can serve it with your favorite http server like `python -m http.server` or `npx serve`, and access the page with your browser.
|
||||||
|
|
||||||
### Docker Install
|
### Docker Install
|
||||||
|
|
||||||
First, install [Docker](https://docs.docker.com/get-docker/) on Linux,
|
First, install [Docker](https://docs.docker.com/get-docker/) on Linux,
|
||||||
|
|||||||
@@ -496,22 +496,28 @@ enum SystemClauseType {
|
|||||||
CryptoDataHKDF,
|
CryptoDataHKDF,
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$crypto_password_hash")))]
|
#[strum_discriminants(strum(props(Arity = "4", Name = "$crypto_password_hash")))]
|
||||||
CryptoPasswordHash,
|
CryptoPasswordHash,
|
||||||
#[strum_discriminants(strum(props(Arity = "7", Name = "$crypto_data_encrypt")))]
|
|
||||||
CryptoDataEncrypt,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "6", Name = "$crypto_data_decrypt")))]
|
|
||||||
CryptoDataDecrypt,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$crypto_curve_scalar_mult")))]
|
#[strum_discriminants(strum(props(Arity = "4", Name = "$crypto_curve_scalar_mult")))]
|
||||||
CryptoCurveScalarMult,
|
CryptoCurveScalarMult,
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_sign")))]
|
|
||||||
Ed25519Sign,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_verify")))]
|
|
||||||
Ed25519Verify,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$ed25519_new_keypair")))]
|
|
||||||
Ed25519NewKeyPair,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "2", Name = "$ed25519_keypair_public_key")))]
|
|
||||||
Ed25519KeyPairPublicKey,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "3", Name = "$curve25519_scalar_mult")))]
|
#[strum_discriminants(strum(props(Arity = "3", Name = "$curve25519_scalar_mult")))]
|
||||||
Curve25519ScalarMult,
|
Curve25519ScalarMult,
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
#[strum_discriminants(strum(props(Arity = "7", Name = "$crypto_data_encrypt")))]
|
||||||
|
CryptoDataEncrypt,
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
#[strum_discriminants(strum(props(Arity = "6", Name = "$crypto_data_decrypt")))]
|
||||||
|
CryptoDataDecrypt,
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_sign")))]
|
||||||
|
Ed25519Sign,
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_verify")))]
|
||||||
|
Ed25519Verify,
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$ed25519_new_keypair")))]
|
||||||
|
Ed25519NewKeyPair,
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
#[strum_discriminants(strum(props(Arity = "2", Name = "$ed25519_keypair_public_key")))]
|
||||||
|
Ed25519KeyPairPublicKey,
|
||||||
#[strum_discriminants(strum(props(Arity = "2", Name = "$first_non_octet")))]
|
#[strum_discriminants(strum(props(Arity = "2", Name = "$first_non_octet")))]
|
||||||
FirstNonOctet,
|
FirstNonOctet,
|
||||||
#[strum_discriminants(strum(props(Arity = "3", Name = "$load_html")))]
|
#[strum_discriminants(strum(props(Arity = "3", Name = "$load_html")))]
|
||||||
@@ -1842,13 +1848,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::CallCryptoDataHash |
|
&Instruction::CallCryptoDataHash |
|
||||||
&Instruction::CallCryptoDataHKDF |
|
&Instruction::CallCryptoDataHKDF |
|
||||||
&Instruction::CallCryptoPasswordHash |
|
&Instruction::CallCryptoPasswordHash |
|
||||||
&Instruction::CallCryptoDataEncrypt |
|
|
||||||
&Instruction::CallCryptoDataDecrypt |
|
|
||||||
&Instruction::CallCryptoCurveScalarMult |
|
&Instruction::CallCryptoCurveScalarMult |
|
||||||
&Instruction::CallEd25519Sign |
|
|
||||||
&Instruction::CallEd25519Verify |
|
|
||||||
&Instruction::CallEd25519NewKeyPair |
|
|
||||||
&Instruction::CallEd25519KeyPairPublicKey |
|
|
||||||
&Instruction::CallCurve25519ScalarMult |
|
&Instruction::CallCurve25519ScalarMult |
|
||||||
&Instruction::CallFirstNonOctet |
|
&Instruction::CallFirstNonOctet |
|
||||||
&Instruction::CallLoadHTML |
|
&Instruction::CallLoadHTML |
|
||||||
@@ -1905,6 +1905,17 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
functor!(atom!("call"), [atom(name), fixnum(arity)])
|
functor!(atom!("call"), [atom(name), fixnum(arity)])
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
&Instruction::CallCryptoDataEncrypt |
|
||||||
|
&Instruction::CallCryptoDataDecrypt |
|
||||||
|
&Instruction::CallEd25519Sign |
|
||||||
|
&Instruction::CallEd25519Verify |
|
||||||
|
&Instruction::CallEd25519NewKeyPair |
|
||||||
|
&Instruction::CallEd25519KeyPairPublicKey => {
|
||||||
|
let (name, arity) = self.to_name_and_arity();
|
||||||
|
functor!(atom!("call"), [atom(name), fixnum(arity)])
|
||||||
|
}
|
||||||
|
//
|
||||||
&Instruction::ExecuteAtomChars |
|
&Instruction::ExecuteAtomChars |
|
||||||
&Instruction::ExecuteAtomCodes |
|
&Instruction::ExecuteAtomCodes |
|
||||||
&Instruction::ExecuteAtomLength |
|
&Instruction::ExecuteAtomLength |
|
||||||
@@ -2070,13 +2081,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::ExecuteCryptoDataHash |
|
&Instruction::ExecuteCryptoDataHash |
|
||||||
&Instruction::ExecuteCryptoDataHKDF |
|
&Instruction::ExecuteCryptoDataHKDF |
|
||||||
&Instruction::ExecuteCryptoPasswordHash |
|
&Instruction::ExecuteCryptoPasswordHash |
|
||||||
&Instruction::ExecuteCryptoDataEncrypt |
|
|
||||||
&Instruction::ExecuteCryptoDataDecrypt |
|
|
||||||
&Instruction::ExecuteCryptoCurveScalarMult |
|
&Instruction::ExecuteCryptoCurveScalarMult |
|
||||||
&Instruction::ExecuteEd25519Sign |
|
|
||||||
&Instruction::ExecuteEd25519Verify |
|
|
||||||
&Instruction::ExecuteEd25519NewKeyPair |
|
|
||||||
&Instruction::ExecuteEd25519KeyPairPublicKey |
|
|
||||||
&Instruction::ExecuteCurve25519ScalarMult |
|
&Instruction::ExecuteCurve25519ScalarMult |
|
||||||
&Instruction::ExecuteFirstNonOctet |
|
&Instruction::ExecuteFirstNonOctet |
|
||||||
&Instruction::ExecuteLoadHTML |
|
&Instruction::ExecuteLoadHTML |
|
||||||
@@ -2133,6 +2138,17 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
functor!(atom!("execute"), [atom(name), fixnum(arity)])
|
functor!(atom!("execute"), [atom(name), fixnum(arity)])
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
|
&Instruction::ExecuteCryptoDataEncrypt |
|
||||||
|
&Instruction::ExecuteCryptoDataDecrypt |
|
||||||
|
&Instruction::ExecuteEd25519Sign |
|
||||||
|
&Instruction::ExecuteEd25519Verify |
|
||||||
|
&Instruction::ExecuteEd25519NewKeyPair |
|
||||||
|
&Instruction::ExecuteEd25519KeyPairPublicKey => {
|
||||||
|
let (name, arity) = self.to_name_and_arity();
|
||||||
|
functor!(atom!("execute"), [atom(name), fixnum(arity)])
|
||||||
|
}
|
||||||
|
//
|
||||||
&Instruction::Deallocate => {
|
&Instruction::Deallocate => {
|
||||||
functor!(atom!("deallocate"))
|
functor!(atom!("deallocate"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ impl std::ops::Deref for AtomString<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "repl")]
|
||||||
impl rustyline::completion::Candidate for AtomString<'_> {
|
impl rustyline::completion::Candidate for AtomString<'_> {
|
||||||
fn display(&self) -> &str {
|
fn display(&self) -> &str {
|
||||||
self.deref()
|
self.deref()
|
||||||
|
|||||||
14
src/lib.rs
14
src/lib.rs
@@ -40,3 +40,17 @@ pub mod types;
|
|||||||
use instructions::instr;
|
use instructions::instr;
|
||||||
|
|
||||||
mod rcu;
|
mod rcu;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn eval_code(s: &str) -> String {
|
||||||
|
use web_sys::console;
|
||||||
|
use machine::mock_wam::*;
|
||||||
|
|
||||||
|
let mut wam = Machine::with_test_streams();
|
||||||
|
let bytes = wam.test_load_string(s);
|
||||||
|
String::from_utf8_lossy(&bytes).to_string()
|
||||||
|
}
|
||||||
|
|||||||
@@ -4742,18 +4742,22 @@ impl Machine {
|
|||||||
self.crypto_password_hash();
|
self.crypto_password_hash();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::CallCryptoDataEncrypt => {
|
&Instruction::CallCryptoDataEncrypt => {
|
||||||
self.crypto_data_encrypt();
|
self.crypto_data_encrypt();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::ExecuteCryptoDataEncrypt => {
|
&Instruction::ExecuteCryptoDataEncrypt => {
|
||||||
self.crypto_data_encrypt();
|
self.crypto_data_encrypt();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::CallCryptoDataDecrypt => {
|
&Instruction::CallCryptoDataDecrypt => {
|
||||||
self.crypto_data_decrypt();
|
self.crypto_data_decrypt();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::ExecuteCryptoDataDecrypt => {
|
&Instruction::ExecuteCryptoDataDecrypt => {
|
||||||
self.crypto_data_decrypt();
|
self.crypto_data_decrypt();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
@@ -4766,34 +4770,42 @@ impl Machine {
|
|||||||
self.crypto_curve_scalar_mult();
|
self.crypto_curve_scalar_mult();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::CallEd25519Sign => {
|
&Instruction::CallEd25519Sign => {
|
||||||
self.ed25519_sign();
|
self.ed25519_sign();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::ExecuteEd25519Sign => {
|
&Instruction::ExecuteEd25519Sign => {
|
||||||
self.ed25519_sign();
|
self.ed25519_sign();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::CallEd25519Verify => {
|
&Instruction::CallEd25519Verify => {
|
||||||
self.ed25519_verify();
|
self.ed25519_verify();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::ExecuteEd25519Verify => {
|
&Instruction::ExecuteEd25519Verify => {
|
||||||
self.ed25519_verify();
|
self.ed25519_verify();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::CallEd25519NewKeyPair => {
|
&Instruction::CallEd25519NewKeyPair => {
|
||||||
self.ed25519_new_key_pair();
|
self.ed25519_new_key_pair();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::ExecuteEd25519NewKeyPair => {
|
&Instruction::ExecuteEd25519NewKeyPair => {
|
||||||
self.ed25519_new_key_pair();
|
self.ed25519_new_key_pair();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::CallEd25519KeyPairPublicKey => {
|
&Instruction::CallEd25519KeyPairPublicKey => {
|
||||||
self.ed25519_key_pair_public_key();
|
self.ed25519_key_pair_public_key();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::ExecuteEd25519KeyPairPublicKey => {
|
&Instruction::ExecuteEd25519KeyPairPublicKey => {
|
||||||
self.ed25519_key_pair_public_key();
|
self.ed25519_key_pair_public_key();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
|
|||||||
@@ -332,6 +332,19 @@ impl Machine {
|
|||||||
self.load_file(file.into(), stream);
|
self.load_file(file.into(), stream);
|
||||||
self.user_output.bytes().map(|b| b.unwrap()).collect()
|
self.user_output.bytes().map(|b| b.unwrap()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn test_load_string(&mut self, code: &str) -> Vec<u8> {
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
let stream = Stream::from_owned_string(
|
||||||
|
code.to_owned(),
|
||||||
|
&mut self.machine_st.arena,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.load_file("<stdin>".into(), stream);
|
||||||
|
self.user_output.bytes().map(|b| b.unwrap()).collect()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -453,9 +453,9 @@ impl Machine {
|
|||||||
let user_output = Stream::stdout(&mut machine_st.arena);
|
let user_output = Stream::stdout(&mut machine_st.arena);
|
||||||
let user_error = Stream::stderr(&mut machine_st.arena);
|
let user_error = Stream::stderr(&mut machine_st.arena);
|
||||||
|
|
||||||
#[cfg(not(target_os = "wasi"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||||
#[cfg(target_os = "wasi")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ use std::process;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use chrono::{offset::Local, DateTime};
|
use chrono::{offset::Local, DateTime};
|
||||||
#[cfg(not(target_os = "wasi"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use cpu_time::ProcessTime;
|
use cpu_time::ProcessTime;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
@@ -71,8 +71,11 @@ use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
|||||||
|
|
||||||
use blake2::{Blake2b, Blake2s};
|
use blake2::{Blake2b, Blake2s};
|
||||||
use ring::rand::{SecureRandom, SystemRandom};
|
use ring::rand::{SecureRandom, SystemRandom};
|
||||||
|
use ring::{digest, hkdf, pbkdf2};
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
use ring::{
|
use ring::{
|
||||||
aead, digest, hkdf, pbkdf2,
|
aead,
|
||||||
signature::{self, KeyPair},
|
signature::{self, KeyPair},
|
||||||
};
|
};
|
||||||
use ripemd160::{Digest, Ripemd160};
|
use ripemd160::{Digest, Ripemd160};
|
||||||
@@ -4290,7 +4293,7 @@ impl Machine {
|
|||||||
self.machine_st.fail = result;
|
self.machine_st.fail = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "wasi"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn cpu_now(&mut self) {
|
pub(crate) fn cpu_now(&mut self) {
|
||||||
let secs = ProcessTime::now().as_duration().as_secs_f64();
|
let secs = ProcessTime::now().as_duration().as_secs_f64();
|
||||||
@@ -4300,7 +4303,7 @@ impl Machine {
|
|||||||
.unify_f64(secs, self.machine_st.registers[1]);
|
.unify_f64(secs, self.machine_st.registers[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "wasi")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn cpu_now(&mut self) {
|
pub(crate) fn cpu_now(&mut self) {
|
||||||
// TODO
|
// TODO
|
||||||
@@ -7382,6 +7385,7 @@ impl Machine {
|
|||||||
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
|
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn crypto_data_encrypt(&mut self) {
|
pub(crate) fn crypto_data_encrypt(&mut self) {
|
||||||
let encoding = cell_as_atom!(self.deref_register(3));
|
let encoding = cell_as_atom!(self.deref_register(3));
|
||||||
@@ -7430,6 +7434,7 @@ impl Machine {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn crypto_data_decrypt(&mut self) {
|
pub(crate) fn crypto_data_decrypt(&mut self) {
|
||||||
let data = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
let data = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
||||||
@@ -7508,6 +7513,7 @@ impl Machine {
|
|||||||
unify!(self.machine_st, self.machine_st.registers[4], uncompressed);
|
unify!(self.machine_st, self.machine_st.registers[4], uncompressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ed25519_new_key_pair(&mut self) {
|
pub(crate) fn ed25519_new_key_pair(&mut self) {
|
||||||
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(rng()).unwrap();
|
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(rng()).unwrap();
|
||||||
@@ -7520,6 +7526,7 @@ impl Machine {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ed25519_key_pair_public_key(&mut self) {
|
pub(crate) fn ed25519_key_pair_public_key(&mut self) {
|
||||||
let bytes = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
let bytes = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
||||||
@@ -7541,6 +7548,7 @@ impl Machine {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ed25519_sign(&mut self) {
|
pub(crate) fn ed25519_sign(&mut self) {
|
||||||
let key = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
let key = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
||||||
@@ -7567,6 +7575,7 @@ impl Machine {
|
|||||||
unify!(self.machine_st, self.machine_st.registers[4], sig_list);
|
unify!(self.machine_st, self.machine_st.registers[4], sig_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto-full")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ed25519_verify(&mut self) {
|
pub(crate) fn ed25519_verify(&mut self) {
|
||||||
let key = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
let key = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
||||||
|
|||||||
Reference in New Issue
Block a user