Fix builds.

This commit is contained in:
Stephen Chung 2021-12-27 22:28:11 +08:00
parent 9c7ced2b80
commit e8b070cbf8
7 changed files with 95 additions and 62 deletions

View File

@ -1,7 +1,7 @@
//! Module that defines the public compilation API of [`Engine`]. //! Module that defines the public compilation API of [`Engine`].
use crate::parser::{ParseResult, ParseState}; use crate::parser::{ParseResult, ParseState};
use crate::{Engine, RhaiResultOf, Scope, AST}; use crate::{Engine, Scope, AST};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -84,7 +84,7 @@ impl Engine {
&self, &self,
scope: &Scope, scope: &Scope,
script: impl AsRef<str>, script: impl AsRef<str>,
) -> RhaiResultOf<AST> { ) -> crate::RhaiResultOf<AST> {
use crate::{ use crate::{
ast::{ASTNode, Expr, Stmt}, ast::{ASTNode, Expr, Stmt},
func::native::shared_take_or_clone, func::native::shared_take_or_clone,
@ -351,14 +351,18 @@ impl Engine {
/// ``` /// ```
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)] #[inline(always)]
pub fn parse_json(&self, json: impl AsRef<str>, has_null: bool) -> RhaiResultOf<crate::Map> { pub fn parse_json(
&self,
json: impl AsRef<str>,
has_null: bool,
) -> crate::RhaiResultOf<crate::Map> {
use crate::tokenizer::Token; use crate::tokenizer::Token;
fn parse_json_inner( fn parse_json_inner(
engine: &Engine, engine: &Engine,
json: &str, json: &str,
has_null: bool, has_null: bool,
) -> RhaiResultOf<crate::Map> { ) -> crate::RhaiResultOf<crate::Map> {
let mut scope = Scope::new(); let mut scope = Scope::new();
let json_text = json.trim_start(); let json_text = json.trim_start();
let scripts = if json_text.starts_with(Token::MapStart.literal_syntax()) { let scripts = if json_text.starts_with(Token::MapStart.literal_syntax()) {

View File

@ -10,8 +10,8 @@ use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
use crate::tokenizer::Token; use crate::tokenizer::Token;
use crate::types::dynamic::{map_std_type_name, AccessMode, Union, Variant}; use crate::types::dynamic::{map_std_type_name, AccessMode, Union, Variant};
use crate::{ use crate::{
calc_fn_params_hash, combine_hashes, Dynamic, FnArgsVec, Identifier, ImmutableString, Module, Dynamic, Identifier, ImmutableString, Module, Position, RhaiError, RhaiResult, RhaiResultOf,
Position, RhaiError, RhaiResult, RhaiResultOf, Scope, Shared, StaticVec, ERR, INT, Scope, Shared, StaticVec, ERR, INT,
}; };
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -399,9 +399,9 @@ impl ChainArgument {
#[inline(always)] #[inline(always)]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[must_use] #[must_use]
pub fn into_fn_call_args(self) -> (FnArgsVec<Dynamic>, Position) { pub fn into_fn_call_args(self) -> (crate::FnArgsVec<Dynamic>, Position) {
match self { match self {
Self::MethodCallArgs(None, pos) => (FnArgsVec::new_const(), pos), Self::MethodCallArgs(None, pos) => (crate::FnArgsVec::new_const(), pos),
Self::MethodCallArgs(Some(mut values), pos) => { Self::MethodCallArgs(Some(mut values), pos) => {
(values.iter_mut().map(std::mem::take).collect(), pos) (values.iter_mut().map(std::mem::take).collect(), pos)
} }
@ -426,7 +426,7 @@ impl ChainArgument {
#[inline(always)] #[inline(always)]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[must_use] #[must_use]
pub fn from_fn_call_args(values: FnArgsVec<Dynamic>, pos: Position) -> Self { pub fn from_fn_call_args(values: crate::FnArgsVec<Dynamic>, pos: Position) -> Self {
if values.is_empty() { if values.is_empty() {
Self::MethodCallArgs(None, pos) Self::MethodCallArgs(None, pos)
} else { } else {
@ -435,6 +435,7 @@ impl ChainArgument {
} }
/// Create an [`IndexValue`][ChainArgument::IndexValue]. /// Create an [`IndexValue`][ChainArgument::IndexValue].
#[inline(always)] #[inline(always)]
#[cfg(not(feature = "no_index"))]
#[must_use] #[must_use]
pub const fn from_index_value(value: Dynamic, pos: Position) -> Self { pub const fn from_index_value(value: Dynamic, pos: Position) -> Self {
Self::IndexValue(value, pos) Self::IndexValue(value, pos)
@ -1865,7 +1866,7 @@ impl Engine {
} = x.as_ref(); } = x.as_ref();
let (values, pos) = args.iter().try_fold( let (values, pos) = args.iter().try_fold(
(FnArgsVec::with_capacity(args.len()), Position::NONE), (crate::FnArgsVec::with_capacity(args.len()), Position::NONE),
|(mut values, mut pos), expr| -> RhaiResultOf<_> { |(mut values, mut pos), expr| -> RhaiResultOf<_> {
let (value, arg_pos) = self.get_arg_value( let (value, arg_pos) = self.get_arg_value(
scope, mods, state, lib, this_ptr, level, expr, constants, scope, mods, state, lib, this_ptr, level, expr, constants,
@ -1911,7 +1912,7 @@ impl Engine {
} = x.as_ref(); } = x.as_ref();
let (values, pos) = args.iter().try_fold( let (values, pos) = args.iter().try_fold(
(FnArgsVec::with_capacity(args.len()), Position::NONE), (crate::FnArgsVec::with_capacity(args.len()), Position::NONE),
|(mut values, mut pos), expr| -> RhaiResultOf<_> { |(mut values, mut pos), expr| -> RhaiResultOf<_> {
let (value, arg_pos) = self.get_arg_value( let (value, arg_pos) = self.get_arg_value(
scope, mods, state, lib, this_ptr, level, expr, constants, scope, mods, state, lib, this_ptr, level, expr, constants,
@ -3246,18 +3247,6 @@ impl Engine {
.map_err(|err| err.fill_position(stmt.position())) .map_err(|err| err.fill_position(stmt.position()))
} }
// Has a system function a Rust-native override?
pub(crate) fn has_native_fn_override(&self, hash_script: u64, arg_types: &[TypeId]) -> bool {
let hash_params = calc_fn_params_hash(arg_types.iter().cloned());
let hash = combine_hashes(hash_script, hash_params);
// First check the global namespace and packages, but skip modules that are standard because
// they should never conflict with system functions.
self.global_modules.iter().filter(|m| !m.standard).any(|m| m.contains_fn(hash))
// Then check sub-modules
|| self.global_sub_modules.values().any(|m| m.contains_qualified_fn(hash))
}
/// Check a result to ensure that the data size is within allowable limit. /// Check a result to ensure that the data size is within allowable limit.
fn check_return_value(&self, mut result: RhaiResult) -> RhaiResult { fn check_return_value(&self, mut result: RhaiResult) -> RhaiResult {
if let Ok(ref mut r) = result { if let Ok(ref mut r) = result {

View File

@ -9,10 +9,14 @@ use crate::func::builtin::get_builtin_binary_op_fn;
use crate::func::hashing::get_hasher; use crate::func::hashing::get_hasher;
use crate::tokenizer::Token; use crate::tokenizer::Token;
use crate::types::dynamic::AccessMode; use crate::types::dynamic::AccessMode;
use crate::{calc_fn_hash, Dynamic, Engine, FnPtr, Position, Scope, StaticVec, AST, INT}; use crate::{
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, Position, Scope,
StaticVec, AST, INT,
};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{ use std::{
any::TypeId,
convert::TryFrom, convert::TryFrom,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
mem, mem,
@ -152,6 +156,18 @@ impl<'a> OptimizerState<'a> {
} }
} }
// Has a system function a Rust-native override?
fn has_native_fn_override(engine: &Engine, hash_script: u64, arg_types: &[TypeId]) -> bool {
let hash_params = calc_fn_params_hash(arg_types.iter().cloned());
let hash = combine_hashes(hash_script, hash_params);
// First check the global namespace and packages, but skip modules that are standard because
// they should never conflict with system functions.
engine.global_modules.iter().filter(|m| !m.standard).any(|m| m.contains_fn(hash))
// Then check sub-modules
|| engine.global_sub_modules.values().any(|m| m.contains_qualified_fn(hash))
}
/// Optimize a block of [statements][Stmt]. /// Optimize a block of [statements][Stmt].
fn optimize_stmt_block( fn optimize_stmt_block(
mut statements: StaticVec<Stmt>, mut statements: StaticVec<Stmt>,
@ -970,7 +986,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
return; return;
} }
// Overloaded operators can override built-in. // Overloaded operators can override built-in.
_ if x.args.len() == 2 && !state.engine.has_native_fn_override(x.hashes.native, arg_types.as_ref()) => { _ if x.args.len() == 2 && !has_native_fn_override(state.engine, x.hashes.native, arg_types.as_ref()) => {
if let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1]) if let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1])
.and_then(|f| { .and_then(|f| {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]

View File

@ -4,7 +4,7 @@
use crate::plugin::*; use crate::plugin::*;
use crate::{ use crate::{
def_package, Blob, Dynamic, ExclusiveRange, InclusiveRange, NativeCallContext, Position, def_package, Blob, Dynamic, ExclusiveRange, InclusiveRange, NativeCallContext, Position,
RhaiResultOf, ERR, INT, RhaiResultOf, INT,
}; };
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -46,7 +46,9 @@ pub mod blob_functions {
// Check if blob will be over max size limit // Check if blob will be over max size limit
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() { if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() {
return Err(ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into()); return Err(
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),
);
} }
let mut blob = Blob::new(); let mut blob = Blob::new();
@ -117,7 +119,9 @@ pub mod blob_functions {
// Check if blob will be over max size limit // Check if blob will be over max size limit
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_array_size() > 0 && (len as usize) > _ctx.engine().max_array_size() { if _ctx.engine().max_array_size() > 0 && (len as usize) > _ctx.engine().max_array_size() {
return Err(ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into()); return Err(
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),
);
} }
if len as usize > blob.len() { if len as usize > blob.len() {

View File

@ -1,6 +1,6 @@
use crate::plugin::*; use crate::plugin::*;
use crate::types::dynamic::Variant; use crate::types::dynamic::Variant;
use crate::{def_package, ExclusiveRange, InclusiveRange, RhaiResultOf, ERR, INT}; use crate::{def_package, ExclusiveRange, InclusiveRange, RhaiResultOf, INT};
use std::iter::{ExactSizeIterator, FusedIterator}; use std::iter::{ExactSizeIterator, FusedIterator};
use std::ops::{Range, RangeInclusive}; use std::ops::{Range, RangeInclusive};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
@ -26,15 +26,15 @@ where
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if let Some(r) = from.checked_add(&step) { if let Some(r) = from.checked_add(&step) {
if r == from { if r == from {
return Err(ERR::ErrorInFunctionCall( return Err(crate::ERR::ErrorInFunctionCall(
"range".to_string(), "range".to_string(),
String::new(), String::new(),
ERR::ErrorArithmetic( crate::ERR::ErrorArithmetic(
"step value cannot be zero".to_string(), "step value cannot be zero".to_string(),
crate::Position::NONE, Position::NONE,
) )
.into(), .into(),
crate::Position::NONE, Position::NONE,
) )
.into()); .into());
} }
@ -123,18 +123,18 @@ impl BitRange {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if offset >= BITS { if offset >= BITS {
return Err(ERR::ErrorBitFieldBounds(BITS, from, crate::Position::NONE).into()); return Err(crate::ERR::ErrorBitFieldBounds(BITS, from, Position::NONE).into());
} }
offset offset
} else { } else {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if let Some(abs_from) = from.checked_abs() { if let Some(abs_from) = from.checked_abs() {
if (abs_from as usize) > BITS { if (abs_from as usize) > BITS {
return Err(ERR::ErrorBitFieldBounds(BITS, from, crate::Position::NONE).into()); return Err(crate::ERR::ErrorBitFieldBounds(BITS, from, Position::NONE).into());
} }
BITS - (abs_from as usize) BITS - (abs_from as usize)
} else { } else {
return Err(ERR::ErrorBitFieldBounds(BITS, from, crate::Position::NONE).into()); return Err(crate::ERR::ErrorBitFieldBounds(BITS, from, Position::NONE).into());
} }
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
@ -328,9 +328,9 @@ def_package! {
pub fn new(from: FLOAT, to: FLOAT, step: FLOAT) -> RhaiResultOf<Self> { pub fn new(from: FLOAT, to: FLOAT, step: FLOAT) -> RhaiResultOf<Self> {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if step == 0.0 { if step == 0.0 {
return Err(ERR::ErrorInFunctionCall("range".to_string(), "".to_string(), return Err(crate::ERR::ErrorInFunctionCall("range".to_string(), "".to_string(),
ERR::ErrorArithmetic("step value cannot be zero".to_string(), crate::Position::NONE).into(), crate::ERR::ErrorArithmetic("step value cannot be zero".to_string(), Position::NONE).into(),
crate::Position::NONE, Position::NONE,
).into()); ).into());
} }
@ -390,9 +390,9 @@ def_package! {
pub fn new(from: Decimal, to: Decimal, step: Decimal) -> RhaiResultOf<Self> { pub fn new(from: Decimal, to: Decimal, step: Decimal) -> RhaiResultOf<Self> {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if step.is_zero() { if step.is_zero() {
return Err(ERR::ErrorInFunctionCall("range".to_string(), "".to_string(), return Err(crate::ERR::ErrorInFunctionCall("range".to_string(), "".to_string(),
ERR::ErrorArithmetic("step value cannot be zero".to_string(), crate::Position::NONE).into(), crate::ERR::ErrorArithmetic("step value cannot be zero".to_string(), Position::NONE).into(),
crate::Position::NONE, Position::NONE,
).into()); ).into());
} }

View File

@ -182,6 +182,7 @@ impl<'e> ParseState<'e> {
/// Get an interned string, creating one if it is not yet interned. /// Get an interned string, creating one if it is not yet interned.
#[inline(always)] #[inline(always)]
#[allow(dead_code)]
#[must_use] #[must_use]
pub fn get_interned_string( pub fn get_interned_string(
&mut self, &mut self,

View File

@ -1,8 +1,9 @@
#[cfg(not(feature = "no_object"))]
use crate::engine::{make_getter, make_setter, FN_GET, FN_SET}; use crate::engine::{make_getter, make_setter, FN_GET, FN_SET};
use crate::{Identifier, ImmutableString}; use crate::{Identifier, ImmutableString};
use std::ops::AddAssign;
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{collections::BTreeMap, ops::AddAssign};
/// _(internals)_ A factory of identifiers from text strings. /// _(internals)_ A factory of identifiers from text strings.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
@ -14,9 +15,11 @@ use std::{collections::BTreeMap, ops::AddAssign};
#[derive(Debug, Clone, Default, Hash)] #[derive(Debug, Clone, Default, Hash)]
pub struct StringsInterner { pub struct StringsInterner {
/// Property getters. /// Property getters.
getters: BTreeMap<Identifier, ImmutableString>, #[cfg(not(feature = "no_object"))]
getters: std::collections::BTreeMap<Identifier, ImmutableString>,
/// Property setters. /// Property setters.
setters: BTreeMap<Identifier, ImmutableString>, #[cfg(not(feature = "no_object"))]
setters: std::collections::BTreeMap<Identifier, ImmutableString>,
} }
impl StringsInterner { impl StringsInterner {
@ -25,8 +28,10 @@ impl StringsInterner {
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
getters: BTreeMap::new(), #[cfg(not(feature = "no_object"))]
setters: BTreeMap::new(), getters: std::collections::BTreeMap::new(),
#[cfg(not(feature = "no_object"))]
setters: std::collections::BTreeMap::new(),
} }
} }
/// Get an identifier from a text string and prefix, adding it to the interner if necessary. /// Get an identifier from a text string and prefix, adding it to the interner if necessary.
@ -41,20 +46,29 @@ impl StringsInterner {
prefix: &'static str, prefix: &'static str,
text: impl AsRef<str> + Into<Identifier> + Into<ImmutableString>, text: impl AsRef<str> + Into<Identifier> + Into<ImmutableString>,
) -> ImmutableString { ) -> ImmutableString {
let (dict, mapper) = match prefix { #[cfg(not(feature = "no_object"))]
"" => return text.into(), {
FN_GET => (&mut self.getters, make_getter as fn(&str) -> String), let (dict, mapper) = match prefix {
FN_SET => (&mut self.setters, make_setter as fn(&str) -> String), "" => return text.into(),
_ => unreachable!("unsupported prefix {}", prefix), FN_GET => (&mut self.getters, make_getter as fn(&str) -> String),
}; FN_SET => (&mut self.setters, make_setter as fn(&str) -> String),
_ => unreachable!("unsupported prefix {}", prefix),
};
if dict.contains_key(text.as_ref()) { if dict.contains_key(text.as_ref()) {
self.getters.get(text.as_ref()).expect("exists").clone() self.getters.get(text.as_ref()).expect("exists").clone()
} else { } else {
let value: ImmutableString = mapper(text.as_ref()).into(); let value: ImmutableString = mapper(text.as_ref()).into();
let text = text.into(); let text = text.into();
dict.insert(text, value.clone()); dict.insert(text, value.clone());
value value
}
}
#[cfg(feature = "no_object")]
match prefix {
"" => return text.into(),
_ => unreachable!("unsupported prefix {}", prefix),
} }
} }
/// Merge another [`IdentifierBuilder`] into this. /// Merge another [`IdentifierBuilder`] into this.
@ -65,7 +79,12 @@ impl StringsInterner {
impl AddAssign for StringsInterner { impl AddAssign for StringsInterner {
#[inline(always)] #[inline(always)]
fn add_assign(&mut self, rhs: Self) { fn add_assign(&mut self, rhs: Self) {
self.getters.extend(rhs.getters.into_iter()); let _rhs = rhs;
self.setters.extend(rhs.setters.into_iter());
#[cfg(not(feature = "no_object"))]
{
self.getters.extend(_rhs.getters.into_iter());
self.setters.extend(_rhs.setters.into_iter());
}
} }
} }