Merge branch 'master' into plugins
This commit is contained in:
@@ -708,7 +708,11 @@ impl Engine {
|
||||
"{} ({})",
|
||||
fn_name,
|
||||
args.iter()
|
||||
.map(|name| self.map_type_name(name.type_name()))
|
||||
.map(|name| if name.is::<ImmutableString>() {
|
||||
"&str | ImmutableString"
|
||||
} else {
|
||||
self.map_type_name(name.type_name())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
@@ -906,6 +910,9 @@ impl Engine {
|
||||
let mut idx_val = idx_values.pop();
|
||||
|
||||
if is_index {
|
||||
#[cfg(feature = "no_index")]
|
||||
unreachable!();
|
||||
|
||||
let pos = rhs.position();
|
||||
|
||||
match rhs {
|
||||
@@ -1292,6 +1299,7 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
_ => {
|
||||
let fn_name = FUNC_INDEXER_GET;
|
||||
let type_name = self.map_type_name(val.type_name());
|
||||
@@ -1305,6 +1313,12 @@ impl Engine {
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "no_index")]
|
||||
_ => Err(Box::new(EvalAltResult::ErrorIndexingType(
|
||||
self.map_type_name(val.type_name()).into(),
|
||||
Position::none(),
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,7 @@ use crate::fn_native::{CallableFunction, FnAny, FnCallArgs};
|
||||
use crate::parser::FnAccess;
|
||||
use crate::plugin::Plugin;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::utils::ImmutableString;
|
||||
|
||||
use crate::stdlib::{any::TypeId, boxed::Box, mem};
|
||||
|
||||
@@ -179,9 +180,16 @@ pub fn by_ref<T: Variant + Clone>(data: &mut Dynamic) -> &mut T {
|
||||
/// Dereference into value.
|
||||
#[inline(always)]
|
||||
pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
|
||||
// We consume the argument and then replace it with () - the argument is not supposed to be used again.
|
||||
// This way, we avoid having to clone the argument again, because it is already a clone when passed here.
|
||||
mem::take(data).cast::<T>()
|
||||
if TypeId::of::<T>() == TypeId::of::<&str>() {
|
||||
// If T is &str, data must be ImmutableString, so map directly to it
|
||||
let ref_str = data.as_str().unwrap();
|
||||
let ref_T = unsafe { mem::transmute::<_, &T>(&ref_str) };
|
||||
ref_T.clone()
|
||||
} else {
|
||||
// We consume the argument and then replace it with () - the argument is not supposed to be used again.
|
||||
// This way, we avoid having to clone the argument again, because it is already a clone when passed here.
|
||||
mem::take(data).cast::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<PL: Plugin> RegisterPlugin<PL> for Engine {
|
||||
@@ -232,6 +240,18 @@ pub fn map_result(
|
||||
data
|
||||
}
|
||||
|
||||
/// Remap `&str` to `ImmutableString`.
|
||||
#[inline(always)]
|
||||
fn map_type_id<T: 'static>() -> TypeId {
|
||||
let id = TypeId::of::<T>();
|
||||
|
||||
if id == TypeId::of::<&str>() {
|
||||
TypeId::of::<ImmutableString>()
|
||||
} else {
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! def_register {
|
||||
() => {
|
||||
def_register!(imp from_pure :);
|
||||
@@ -256,7 +276,7 @@ macro_rules! def_register {
|
||||
{
|
||||
fn register_fn(&mut self, name: &str, f: FN) {
|
||||
self.global_module.set_fn(name, FnAccess::Public,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
&[$(map_type_id::<$par>()),*],
|
||||
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $clone),*))
|
||||
);
|
||||
}
|
||||
@@ -273,7 +293,7 @@ macro_rules! def_register {
|
||||
{
|
||||
fn register_result_fn(&mut self, name: &str, f: FN) {
|
||||
self.global_module.set_fn(name, FnAccess::Public,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
&[$(map_type_id::<$par>()),*],
|
||||
CallableFunction::$abi(make_func!(f : map_result ; $($par => $clone),*))
|
||||
);
|
||||
}
|
||||
|
17
src/utils.rs
17
src/utils.rs
@@ -190,8 +190,9 @@ impl<T: Clone> Clone for StaticVec<T> {
|
||||
|
||||
if self.is_fixed_storage() {
|
||||
for x in 0..self.len {
|
||||
let item: &T = unsafe { mem::transmute(self.list.get(x).unwrap()) };
|
||||
value.list[x] = MaybeUninit::new(item.clone());
|
||||
let item = self.list.get(x).unwrap();
|
||||
let item_value = unsafe { mem::transmute::<_, &T>(item) };
|
||||
value.list[x] = MaybeUninit::new(item_value.clone());
|
||||
}
|
||||
} else {
|
||||
value.more = self.more.clone();
|
||||
@@ -424,7 +425,7 @@ impl<T> StaticVec<T> {
|
||||
panic!("index OOB in StaticVec");
|
||||
}
|
||||
|
||||
let list: &[T; MAX_STATIC_VEC] = unsafe { mem::transmute(&self.list) };
|
||||
let list = unsafe { mem::transmute::<_, &[T; MAX_STATIC_VEC]>(&self.list) };
|
||||
|
||||
if self.is_fixed_storage() {
|
||||
list.get(index).unwrap()
|
||||
@@ -442,7 +443,7 @@ impl<T> StaticVec<T> {
|
||||
panic!("index OOB in StaticVec");
|
||||
}
|
||||
|
||||
let list: &mut [T; MAX_STATIC_VEC] = unsafe { mem::transmute(&mut self.list) };
|
||||
let list = unsafe { mem::transmute::<_, &mut [T; MAX_STATIC_VEC]>(&mut self.list) };
|
||||
|
||||
if self.is_fixed_storage() {
|
||||
list.get_mut(index).unwrap()
|
||||
@@ -452,7 +453,7 @@ impl<T> StaticVec<T> {
|
||||
}
|
||||
/// Get an iterator to entries in the `StaticVec`.
|
||||
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
||||
let list: &[T; MAX_STATIC_VEC] = unsafe { mem::transmute(&self.list) };
|
||||
let list = unsafe { mem::transmute::<_, &[T; MAX_STATIC_VEC]>(&self.list) };
|
||||
|
||||
if self.is_fixed_storage() {
|
||||
list[..self.len].iter()
|
||||
@@ -462,7 +463,7 @@ impl<T> StaticVec<T> {
|
||||
}
|
||||
/// Get a mutable iterator to entries in the `StaticVec`.
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
||||
let list: &mut [T; MAX_STATIC_VEC] = unsafe { mem::transmute(&mut self.list) };
|
||||
let list = unsafe { mem::transmute::<_, &mut [T; MAX_STATIC_VEC]>(&mut self.list) };
|
||||
|
||||
if self.is_fixed_storage() {
|
||||
list[..self.len].iter_mut()
|
||||
@@ -549,7 +550,7 @@ impl<T: fmt::Debug> fmt::Debug for StaticVec<T> {
|
||||
|
||||
impl<T> AsRef<[T]> for StaticVec<T> {
|
||||
fn as_ref(&self) -> &[T] {
|
||||
let list: &[T; MAX_STATIC_VEC] = unsafe { mem::transmute(&self.list) };
|
||||
let list = unsafe { mem::transmute::<_, &[T; MAX_STATIC_VEC]>(&self.list) };
|
||||
|
||||
if self.is_fixed_storage() {
|
||||
&list[..self.len]
|
||||
@@ -561,7 +562,7 @@ impl<T> AsRef<[T]> for StaticVec<T> {
|
||||
|
||||
impl<T> AsMut<[T]> for StaticVec<T> {
|
||||
fn as_mut(&mut self) -> &mut [T] {
|
||||
let list: &mut [T; MAX_STATIC_VEC] = unsafe { mem::transmute(&mut self.list) };
|
||||
let list = unsafe { mem::transmute::<_, &mut [T; MAX_STATIC_VEC]>(&mut self.list) };
|
||||
|
||||
if self.is_fixed_storage() {
|
||||
&mut list[..self.len]
|
||||
|
Reference in New Issue
Block a user