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`].
use crate::parser::{ParseResult, ParseState};
use crate::{Engine, RhaiResultOf, Scope, AST};
use crate::{Engine, Scope, AST};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
@ -84,7 +84,7 @@ impl Engine {
&self,
scope: &Scope,
script: impl AsRef<str>,
) -> RhaiResultOf<AST> {
) -> crate::RhaiResultOf<AST> {
use crate::{
ast::{ASTNode, Expr, Stmt},
func::native::shared_take_or_clone,
@ -351,14 +351,18 @@ impl Engine {
/// ```
#[cfg(not(feature = "no_object"))]
#[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;
fn parse_json_inner(
engine: &Engine,
json: &str,
has_null: bool,
) -> RhaiResultOf<crate::Map> {
) -> crate::RhaiResultOf<crate::Map> {
let mut scope = Scope::new();
let json_text = json.trim_start();
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::types::dynamic::{map_std_type_name, AccessMode, Union, Variant};
use crate::{
calc_fn_params_hash, combine_hashes, Dynamic, FnArgsVec, Identifier, ImmutableString, Module,
Position, RhaiError, RhaiResult, RhaiResultOf, Scope, Shared, StaticVec, ERR, INT,
Dynamic, Identifier, ImmutableString, Module, Position, RhaiError, RhaiResult, RhaiResultOf,
Scope, Shared, StaticVec, ERR, INT,
};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
@ -399,9 +399,9 @@ impl ChainArgument {
#[inline(always)]
#[cfg(not(feature = "no_object"))]
#[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 {
Self::MethodCallArgs(None, pos) => (FnArgsVec::new_const(), pos),
Self::MethodCallArgs(None, pos) => (crate::FnArgsVec::new_const(), pos),
Self::MethodCallArgs(Some(mut values), pos) => {
(values.iter_mut().map(std::mem::take).collect(), pos)
}
@ -426,7 +426,7 @@ impl ChainArgument {
#[inline(always)]
#[cfg(not(feature = "no_object"))]
#[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() {
Self::MethodCallArgs(None, pos)
} else {
@ -435,6 +435,7 @@ impl ChainArgument {
}
/// Create an [`IndexValue`][ChainArgument::IndexValue].
#[inline(always)]
#[cfg(not(feature = "no_index"))]
#[must_use]
pub const fn from_index_value(value: Dynamic, pos: Position) -> Self {
Self::IndexValue(value, pos)
@ -1865,7 +1866,7 @@ impl Engine {
} = x.as_ref();
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<_> {
let (value, arg_pos) = self.get_arg_value(
scope, mods, state, lib, this_ptr, level, expr, constants,
@ -1911,7 +1912,7 @@ impl Engine {
} = x.as_ref();
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<_> {
let (value, arg_pos) = self.get_arg_value(
scope, mods, state, lib, this_ptr, level, expr, constants,
@ -3246,18 +3247,6 @@ impl Engine {
.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.
fn check_return_value(&self, mut result: RhaiResult) -> RhaiResult {
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::tokenizer::Token;
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")]
use std::prelude::v1::*;
use std::{
any::TypeId,
convert::TryFrom,
hash::{Hash, Hasher},
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].
fn optimize_stmt_block(
mut statements: StaticVec<Stmt>,
@ -970,7 +986,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
return;
}
// 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])
.and_then(|f| {
#[cfg(not(feature = "no_function"))]

View File

@ -4,7 +4,7 @@
use crate::plugin::*;
use crate::{
def_package, Blob, Dynamic, ExclusiveRange, InclusiveRange, NativeCallContext, Position,
RhaiResultOf, ERR, INT,
RhaiResultOf, INT,
};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
@ -46,7 +46,9 @@ pub mod blob_functions {
// Check if blob will be over max size limit
#[cfg(not(feature = "unchecked"))]
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();
@ -117,7 +119,9 @@ pub mod blob_functions {
// Check if blob will be over max size limit
#[cfg(not(feature = "unchecked"))]
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() {

View File

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

View File

@ -182,6 +182,7 @@ impl<'e> ParseState<'e> {
/// Get an interned string, creating one if it is not yet interned.
#[inline(always)]
#[allow(dead_code)]
#[must_use]
pub fn get_interned_string(
&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::{Identifier, ImmutableString};
use std::ops::AddAssign;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{collections::BTreeMap, ops::AddAssign};
/// _(internals)_ A factory of identifiers from text strings.
/// Exported under the `internals` feature only.
@ -14,9 +15,11 @@ use std::{collections::BTreeMap, ops::AddAssign};
#[derive(Debug, Clone, Default, Hash)]
pub struct StringsInterner {
/// Property getters.
getters: BTreeMap<Identifier, ImmutableString>,
#[cfg(not(feature = "no_object"))]
getters: std::collections::BTreeMap<Identifier, ImmutableString>,
/// Property setters.
setters: BTreeMap<Identifier, ImmutableString>,
#[cfg(not(feature = "no_object"))]
setters: std::collections::BTreeMap<Identifier, ImmutableString>,
}
impl StringsInterner {
@ -25,8 +28,10 @@ impl StringsInterner {
#[must_use]
pub fn new() -> Self {
Self {
getters: BTreeMap::new(),
setters: BTreeMap::new(),
#[cfg(not(feature = "no_object"))]
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.
@ -41,20 +46,29 @@ impl StringsInterner {
prefix: &'static str,
text: impl AsRef<str> + Into<Identifier> + Into<ImmutableString>,
) -> ImmutableString {
let (dict, mapper) = match prefix {
"" => return text.into(),
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),
};
#[cfg(not(feature = "no_object"))]
{
let (dict, mapper) = match prefix {
"" => return text.into(),
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()) {
self.getters.get(text.as_ref()).expect("exists").clone()
} else {
let value: ImmutableString = mapper(text.as_ref()).into();
let text = text.into();
dict.insert(text, value.clone());
value
if dict.contains_key(text.as_ref()) {
self.getters.get(text.as_ref()).expect("exists").clone()
} else {
let value: ImmutableString = mapper(text.as_ref()).into();
let text = text.into();
dict.insert(text, value.clone());
value
}
}
#[cfg(feature = "no_object")]
match prefix {
"" => return text.into(),
_ => unreachable!("unsupported prefix {}", prefix),
}
}
/// Merge another [`IdentifierBuilder`] into this.
@ -65,7 +79,12 @@ impl StringsInterner {
impl AddAssign for StringsInterner {
#[inline(always)]
fn add_assign(&mut self, rhs: Self) {
self.getters.extend(rhs.getters.into_iter());
self.setters.extend(rhs.setters.into_iter());
let _rhs = rhs;
#[cfg(not(feature = "no_object"))]
{
self.getters.extend(_rhs.getters.into_iter());
self.setters.extend(_rhs.setters.into_iter());
}
}
}