Gate WASM target.
This commit is contained in:
parent
b6e1f652b6
commit
7f4f737ff2
32
README.md
32
README.md
@ -11,6 +11,11 @@ Rhai - Embedded Scripting for Rust
|
||||
Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way
|
||||
to add scripting to any application.
|
||||
|
||||
Supported targets
|
||||
-----------------
|
||||
|
||||
* All common targets, including [WASM] and `no-std`.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
@ -27,13 +32,11 @@ Features
|
||||
* Sand-boxed - the scripting [`Engine`], if declared immutable, cannot mutate the containing environment unless explicitly permitted (e.g. via a `RefCell`).
|
||||
* Rugged - protection against malicious attacks (such as [stack-overflow](#maximum-call-stack-depth), [over-sized data](#maximum-length-of-strings), and [runaway scripts](#maximum-number-of-operations) etc.) that may come from untrusted third-party user-land scripts.
|
||||
* Track script evaluation [progress](#tracking-progress-and-force-terminate-script-run) and manually terminate a script run.
|
||||
* [`no-std`](#optional-features) support.
|
||||
* Supports compiling to `WASM`, optionally with [minimal builds](#minimal-builds).
|
||||
* [Function overloading](#function-overloading).
|
||||
* [Operator overloading](#operator-overloading).
|
||||
* Organize code base with dynamically-loadable [modules].
|
||||
* Scripts are [optimized](#script-optimization) (useful for template-based machine-generated scripts) for repeated evaluations.
|
||||
* Support for [minimal builds](#minimal-builds) by excluding unneeded language [features](#optional-features).
|
||||
* Support for [minimal builds] by excluding unneeded language [features](#optional-features).
|
||||
* Very few additional dependencies (right now only [`num-traits`](https://crates.io/crates/num-traits/)
|
||||
to do checked arithmetic operations); for [`no-std`](#optional-features) builds, a number of additional dependencies are
|
||||
pulled in to provide for functionalities that used to be in `std`.
|
||||
@ -142,8 +145,10 @@ Making [`Dynamic`] small helps performance due to better cache efficiency.
|
||||
|
||||
### Minimal builds
|
||||
|
||||
[minimal builds]: #minimal-builds
|
||||
|
||||
In order to compile a _minimal_build - i.e. a build optimized for size - perhaps for `no-std` embedded targets or for
|
||||
compiling to `WASM`, it is essential that the correct linker flags are used in `cargo.toml`:
|
||||
compiling to [WASM], it is essential that the correct linker flags are used in `cargo.toml`:
|
||||
|
||||
```toml
|
||||
[profile.release]
|
||||
@ -167,8 +172,19 @@ A _raw_ engine supports, out of the box, only a very [restricted set](#built-in-
|
||||
Selectively include other necessary functionalities by loading specific [packages] to minimize the footprint.
|
||||
Packages are sharable (even across threads via the [`sync`] feature), so they only have to be created once.
|
||||
|
||||
Related
|
||||
-------
|
||||
### Compiling to WebAssembly (WASM)
|
||||
|
||||
[WASM]: #compiling-to-WebAssembly-wasm
|
||||
|
||||
It is possible to use Rhai when compiling to WebAssembly (WASM), but certain features will not be available,
|
||||
such as the script file API's and loading modules from external script files.
|
||||
|
||||
Also look into [minimal builds] to reduce generated WASM size. As of this version, a typical, full-featured
|
||||
Rhai scripting engine compiles to a single WASM file around 200KB gzipped. When excluding features that are
|
||||
marginal in WASM environment, the gzipped payload can be further shrunk to 160KB.
|
||||
|
||||
Related Resources
|
||||
-----------------
|
||||
|
||||
Other cool projects to check out:
|
||||
|
||||
@ -2454,8 +2470,8 @@ which simply loads a script file based on the path (with `.rhai` extension attac
|
||||
Built-in module resolvers are grouped under the `rhai::module_resolvers` module namespace.
|
||||
|
||||
| Module Resolver | Description |
|
||||
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `FileModuleResolver` | The default module resolution service, not available under [`no_std`]. Loads a script file (based off the current directory) with `.rhai` extension.<br/>The base directory can be changed via the `FileModuleResolver::new_with_path()` constructor function.<br/>`FileModuleResolver::create_module()` loads a script file and returns a module. |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `FileModuleResolver` | The default module resolution service, not available under [`no_std`] or [WASM] builds. Loads a script file (based off the current directory) with `.rhai` extension.<br/>The base directory can be changed via the `FileModuleResolver::new_with_path()` constructor function.<br/>`FileModuleResolver::create_module()` loads a script file and returns a module. |
|
||||
| `StaticModuleResolver` | Loads modules that are statically added. This can be used under [`no_std`]. |
|
||||
|
||||
An [`Engine`]'s module resolver is set via a call to `Engine::set_module_resolver`:
|
||||
|
@ -5,7 +5,7 @@ Version 0.15.1
|
||||
==============
|
||||
|
||||
This is a minor release which enables updating indexers (via registered indexer setters) and supports functions
|
||||
with `&str` parameters (maps transparently to `ImmutableString`).
|
||||
with `&str` parameters (maps transparently to `ImmutableString`). WASM is also a tested target.
|
||||
|
||||
Buf fix
|
||||
-------
|
||||
@ -28,7 +28,7 @@ New features
|
||||
* `Engine:register_fn` and `Engine:register_result_fn` accepts functions that take parameters of type `&str` (immutable string slice), which maps directly to `ImmutableString`. This is to avoid needing wrappers for functions taking string parameters.
|
||||
* Set maximum limit on data sizes: `Engine::set_max_string_size`, `Engine::set_max_array_size` and `Engine::set_max_map_size`.
|
||||
* Supports trailing commas on array literals, object map literals, function definitions and function calls.
|
||||
* Supports compiling to `WASM`.
|
||||
* Enhances support for compiling to WASM.
|
||||
|
||||
Version 0.15.0
|
||||
==============
|
||||
|
14
src/api.rs
14
src/api.rs
@ -555,6 +555,8 @@ impl Engine {
|
||||
|
||||
/// Read the contents of a file into a string.
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
fn read_file(path: PathBuf) -> Result<String, Box<EvalAltResult>> {
|
||||
let mut f = File::open(path.clone()).map_err(|err| {
|
||||
Box::new(EvalAltResult::ErrorReadingScriptFile(
|
||||
@ -598,6 +600,8 @@ impl Engine {
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub fn compile_file(&self, path: PathBuf) -> Result<AST, Box<EvalAltResult>> {
|
||||
self.compile_file_with_scope(&Scope::new(), path)
|
||||
}
|
||||
@ -634,6 +638,8 @@ impl Engine {
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub fn compile_file_with_scope(
|
||||
&self,
|
||||
scope: &Scope,
|
||||
@ -775,6 +781,8 @@ impl Engine {
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub fn eval_file<T: Variant + Clone>(&self, path: PathBuf) -> Result<T, Box<EvalAltResult>> {
|
||||
Self::read_file(path).and_then(|contents| self.eval::<T>(&contents))
|
||||
}
|
||||
@ -799,6 +807,8 @@ impl Engine {
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub fn eval_file_with_scope<T: Variant + Clone>(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
@ -1004,6 +1014,8 @@ impl Engine {
|
||||
/// Evaluate a file, but throw away the result and only return error (if any).
|
||||
/// Useful for when you don't need the result, but still need to keep track of possible errors.
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub fn consume_file(&self, path: PathBuf) -> Result<(), Box<EvalAltResult>> {
|
||||
Self::read_file(path).and_then(|contents| self.consume(&contents))
|
||||
}
|
||||
@ -1011,6 +1023,8 @@ impl Engine {
|
||||
/// Evaluate a file with own scope, but throw away the result and only return error (if any).
|
||||
/// Useful for when you don't need the result, but still need to keep track of possible errors.
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub fn consume_file_with_scope(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
|
@ -292,8 +292,15 @@ impl Default for Engine {
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
module_resolver: Some(Box::new(resolvers::FileModuleResolver::new())),
|
||||
#[cfg(any(feature = "no_module", feature = "no_std"))]
|
||||
#[cfg(any(
|
||||
feature = "no_module",
|
||||
feature = "no_std",
|
||||
target_arch = "wasm32",
|
||||
target_arch = "wasm64"
|
||||
))]
|
||||
module_resolver: None,
|
||||
|
||||
type_names: HashMap::new(),
|
||||
@ -373,6 +380,8 @@ fn extract_prop_from_setter(fn_name: &str) -> Option<&str> {
|
||||
/// Print/debug to stdout
|
||||
fn default_print(s: &str) {
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
println!("{}", s);
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@
|
||||
//! engine.register_fn("compute", compute_something);
|
||||
//!
|
||||
//! # #[cfg(not(feature = "no_std"))]
|
||||
//! # #[cfg(not(target_arch = "wasm32"))]
|
||||
//! # #[cfg(not(target_arch = "wasm64"))]
|
||||
//! assert_eq!(
|
||||
//! // Evaluate the script, expects a 'bool' return
|
||||
//! engine.eval_file::<bool>("my_script.rhai".into())?,
|
||||
|
@ -1054,6 +1054,8 @@ pub trait ModuleResolver: SendSync {
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
pub mod resolvers {
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub use super::file::FileModuleResolver;
|
||||
pub use super::stat::StaticModuleResolver;
|
||||
}
|
||||
@ -1063,6 +1065,8 @@ pub mod resolvers {}
|
||||
/// Script file-based module resolver.
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
mod file {
|
||||
use super::*;
|
||||
use crate::stdlib::path::PathBuf;
|
||||
|
@ -33,6 +33,8 @@ pub use pkg_std::StandardPackage;
|
||||
pub use string_basic::BasicStringPackage;
|
||||
pub use string_more::MoreStringPackage;
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
pub use time_basic::BasicTimePackage;
|
||||
|
||||
/// Trait that all packages must implement.
|
||||
|
@ -13,6 +13,8 @@ use crate::stdlib::{
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
use crate::stdlib::path::PathBuf;
|
||||
|
||||
/// Evaluation result.
|
||||
@ -29,6 +31,8 @@ pub enum EvalAltResult {
|
||||
///
|
||||
/// Never appears under the `no_std` feature.
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
ErrorReadingScriptFile(PathBuf, Position, std::io::Error),
|
||||
|
||||
/// Call to an unknown function. Wrapped value is the name of the function.
|
||||
@ -101,6 +105,8 @@ impl EvalAltResult {
|
||||
pub(crate) fn desc(&self) -> &str {
|
||||
match self {
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
Self::ErrorReadingScriptFile(_, _, _) => "Cannot read from script file",
|
||||
|
||||
Self::ErrorParsing(p, _) => p.desc(),
|
||||
@ -160,6 +166,8 @@ impl fmt::Display for EvalAltResult {
|
||||
|
||||
match self {
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
Self::ErrorReadingScriptFile(path, _, err) => {
|
||||
write!(f, "{} '{}': {}", desc, path.display(), err)?
|
||||
}
|
||||
@ -259,6 +267,8 @@ impl EvalAltResult {
|
||||
pub fn position(&self) -> Position {
|
||||
match self {
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
Self::ErrorReadingScriptFile(_, pos, _) => *pos,
|
||||
|
||||
Self::ErrorParsing(_, pos)
|
||||
@ -297,6 +307,8 @@ impl EvalAltResult {
|
||||
pub fn set_position(&mut self, new_position: Position) {
|
||||
match self {
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(not(target_arch = "wasm64"))]
|
||||
Self::ErrorReadingScriptFile(_, pos, _) => *pos = new_position,
|
||||
|
||||
Self::ErrorParsing(_, pos)
|
||||
|
@ -1,4 +1,6 @@
|
||||
#![cfg(not(feature = "no_std"))]
|
||||
#![cfg(not(target_arch = "wasm32"))]
|
||||
#![cfg(not(target_arch = "wasm64"))]
|
||||
|
||||
use rhai::{Engine, EvalAltResult, INT};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user