Use deref for Target.
This commit is contained in:
parent
807a14eaa2
commit
199df9aa4a
@ -18,7 +18,7 @@ use crate::stdlib::{
|
|||||||
fmt, format,
|
fmt, format,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
num::{NonZeroU8, NonZeroUsize},
|
num::{NonZeroU8, NonZeroUsize},
|
||||||
ops::DerefMut,
|
ops::{Deref, DerefMut},
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
@ -467,9 +467,11 @@ impl<'a> From<&'a mut Dynamic> for Target<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<Dynamic> for Target<'_> {
|
impl Deref for Target<'_> {
|
||||||
|
type Target = Dynamic;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_ref(&self) -> &Dynamic {
|
fn deref(&self) -> &Dynamic {
|
||||||
match self {
|
match self {
|
||||||
Self::Ref(r) => *r,
|
Self::Ref(r) => *r,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -482,9 +484,16 @@ impl AsRef<Dynamic> for Target<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsMut<Dynamic> for Target<'_> {
|
impl AsRef<Dynamic> for Target<'_> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_mut(&mut self) -> &mut Dynamic {
|
fn as_ref(&self) -> &Dynamic {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Target<'_> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn deref_mut(&mut self) -> &mut Dynamic {
|
||||||
match self {
|
match self {
|
||||||
Self::Ref(r) => *r,
|
Self::Ref(r) => *r,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -497,6 +506,13 @@ impl AsMut<Dynamic> for Target<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsMut<Dynamic> for Target<'_> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn as_mut(&mut self) -> &mut Dynamic {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: T) -> Self {
|
fn from(value: T) -> Self {
|
||||||
@ -1105,8 +1121,6 @@ impl Engine {
|
|||||||
// Pop the last index value
|
// Pop the last index value
|
||||||
let idx_val = idx_values.pop().unwrap();
|
let idx_val = idx_values.pop().unwrap();
|
||||||
|
|
||||||
let target_val = target.as_mut();
|
|
||||||
|
|
||||||
match chain_type {
|
match chain_type {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
ChainType::Index => {
|
ChainType::Index => {
|
||||||
@ -1118,8 +1132,7 @@ impl Engine {
|
|||||||
let idx_pos = x.lhs.position();
|
let idx_pos = x.lhs.position();
|
||||||
let idx_val = idx_val.as_index_value();
|
let idx_val = idx_val.as_index_value();
|
||||||
let obj_ptr = &mut self.get_indexed_mut(
|
let obj_ptr = &mut self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, idx_val, idx_pos, false, is_ref, true,
|
mods, state, lib, target, idx_val, idx_pos, false, is_ref, true, level,
|
||||||
level,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
@ -1137,7 +1150,7 @@ impl Engine {
|
|||||||
|
|
||||||
// `call_setter` is introduced to bypass double mutable borrowing of target
|
// `call_setter` is introduced to bypass double mutable borrowing of target
|
||||||
let _call_setter = match self.get_indexed_mut(
|
let _call_setter = match self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, idx_val, pos, true, is_ref, false, level,
|
mods, state, lib, target, idx_val, pos, true, is_ref, false, level,
|
||||||
) {
|
) {
|
||||||
// Indexed value is a reference - update directly
|
// Indexed value is a reference - update directly
|
||||||
Ok(obj_ptr) => {
|
Ok(obj_ptr) => {
|
||||||
@ -1158,12 +1171,12 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if let Some(mut new_val) = _call_setter {
|
if let Some(mut new_val) = _call_setter {
|
||||||
let val_type_name = target_val.type_name();
|
let val_type_name = target.type_name();
|
||||||
let ((_, val_pos), _) = new_val;
|
let ((_, val_pos), _) = new_val;
|
||||||
|
|
||||||
let hash_set =
|
let hash_set =
|
||||||
FnCallHash::from_native(calc_fn_hash(empty(), FN_IDX_SET, 3));
|
FnCallHash::from_native(calc_fn_hash(empty(), FN_IDX_SET, 3));
|
||||||
let args = &mut [target_val, &mut idx_val2, &mut (new_val.0).0];
|
let args = &mut [target, &mut idx_val2, &mut (new_val.0).0];
|
||||||
|
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true,
|
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true,
|
||||||
@ -1188,7 +1201,7 @@ impl Engine {
|
|||||||
_ => {
|
_ => {
|
||||||
let idx_val = idx_val.as_index_value();
|
let idx_val = idx_val.as_index_value();
|
||||||
self.get_indexed_mut(
|
self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, idx_val, pos, false, is_ref, true, level,
|
mods, state, lib, target, idx_val, pos, false, is_ref, true, level,
|
||||||
)
|
)
|
||||||
.map(|v| (v.take_or_clone(), false))
|
.map(|v| (v.take_or_clone(), false))
|
||||||
}
|
}
|
||||||
@ -1215,11 +1228,11 @@ impl Engine {
|
|||||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||||
}
|
}
|
||||||
// {xxx:map}.id op= ???
|
// {xxx:map}.id op= ???
|
||||||
Expr::Property(x) if target_val.is::<Map>() && new_val.is_some() => {
|
Expr::Property(x) if target.is::<Map>() && new_val.is_some() => {
|
||||||
let Ident { name, pos, .. } = &x.2;
|
let Ident { name, pos, .. } = &x.2;
|
||||||
let index = name.into();
|
let index = name.into();
|
||||||
let val = self.get_indexed_mut(
|
let val = self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, index, *pos, true, is_ref, false, level,
|
mods, state, lib, target, index, *pos, true, is_ref, false, level,
|
||||||
)?;
|
)?;
|
||||||
let ((new_val, new_pos), (op_info, op_pos)) = new_val.unwrap();
|
let ((new_val, new_pos), (op_info, op_pos)) = new_val.unwrap();
|
||||||
self.eval_op_assignment(
|
self.eval_op_assignment(
|
||||||
@ -1228,11 +1241,11 @@ impl Engine {
|
|||||||
Ok((Dynamic::UNIT, true))
|
Ok((Dynamic::UNIT, true))
|
||||||
}
|
}
|
||||||
// {xxx:map}.id
|
// {xxx:map}.id
|
||||||
Expr::Property(x) if target_val.is::<Map>() => {
|
Expr::Property(x) if target.is::<Map>() => {
|
||||||
let Ident { name, pos, .. } = &x.2;
|
let Ident { name, pos, .. } = &x.2;
|
||||||
let index = name.into();
|
let index = name.into();
|
||||||
let val = self.get_indexed_mut(
|
let val = self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, index, *pos, false, is_ref, false, level,
|
mods, state, lib, target, index, *pos, false, is_ref, false, level,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok((val.take_or_clone(), false))
|
Ok((val.take_or_clone(), false))
|
||||||
@ -1269,7 +1282,7 @@ impl Engine {
|
|||||||
Expr::Property(x) => {
|
Expr::Property(x) => {
|
||||||
let ((getter, hash_get), _, Ident { pos, .. }) = x.as_ref();
|
let ((getter, hash_get), _, Ident { pos, .. }) = x.as_ref();
|
||||||
let hash = FnCallHash::from_native(*hash_get);
|
let hash = FnCallHash::from_native(*hash_get);
|
||||||
let mut args = [target_val];
|
let mut args = [target.as_mut()];
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos, None,
|
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos, None,
|
||||||
level,
|
level,
|
||||||
@ -1277,13 +1290,13 @@ impl Engine {
|
|||||||
.map(|(v, _)| (v, false))
|
.map(|(v, _)| (v, false))
|
||||||
}
|
}
|
||||||
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
|
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
|
||||||
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target_val.is::<Map>() => {
|
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target.is::<Map>() => {
|
||||||
let mut val = match &x.lhs {
|
let mut val = match &x.lhs {
|
||||||
Expr::Property(p) => {
|
Expr::Property(p) => {
|
||||||
let Ident { name, pos, .. } = &p.2;
|
let Ident { name, pos, .. } = &p.2;
|
||||||
let index = name.into();
|
let index = name.into();
|
||||||
self.get_indexed_mut(
|
self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, index, *pos, false, is_ref, true,
|
mods, state, lib, target, index, *pos, false, is_ref, true,
|
||||||
level,
|
level,
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
@ -1319,7 +1332,7 @@ impl Engine {
|
|||||||
p.as_ref();
|
p.as_ref();
|
||||||
let hash_get = FnCallHash::from_native(*hash_get);
|
let hash_get = FnCallHash::from_native(*hash_get);
|
||||||
let hash_set = FnCallHash::from_native(*hash_set);
|
let hash_set = FnCallHash::from_native(*hash_set);
|
||||||
let arg_values = &mut [target_val, &mut Default::default()];
|
let arg_values = &mut [target.as_mut(), &mut Default::default()];
|
||||||
let args = &mut arg_values[..1];
|
let args = &mut arg_values[..1];
|
||||||
let (mut val, updated) = self.exec_fn_call(
|
let (mut val, updated) = self.exec_fn_call(
|
||||||
mods, state, lib, getter, hash_get, args, is_ref, true, *pos,
|
mods, state, lib, getter, hash_get, args, is_ref, true, *pos,
|
||||||
@ -1432,7 +1445,7 @@ impl Engine {
|
|||||||
self.search_namespace(scope, mods, state, lib, this_ptr, lhs)?;
|
self.search_namespace(scope, mods, state, lib, this_ptr, lhs)?;
|
||||||
|
|
||||||
// Constants cannot be modified
|
// Constants cannot be modified
|
||||||
if target.as_ref().is_read_only() && new_val.is_some() {
|
if target.is_read_only() && new_val.is_some() {
|
||||||
return EvalAltResult::ErrorAssignmentToConstant(x.2.to_string(), pos).into();
|
return EvalAltResult::ErrorAssignmentToConstant(x.2.to_string(), pos).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1977,7 +1990,7 @@ impl Engine {
|
|||||||
mut new_value: Dynamic,
|
mut new_value: Dynamic,
|
||||||
new_value_pos: Position,
|
new_value_pos: Position,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
if target.as_ref().is_read_only() {
|
if target.is_read_only() {
|
||||||
unreachable!("LHS should not be read-only");
|
unreachable!("LHS should not be read-only");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1996,10 +2009,10 @@ impl Engine {
|
|||||||
let target_is_shared = false;
|
let target_is_shared = false;
|
||||||
|
|
||||||
if target_is_shared {
|
if target_is_shared {
|
||||||
lock_guard = target.as_mut().write_lock::<Dynamic>().unwrap();
|
lock_guard = target.write_lock::<Dynamic>().unwrap();
|
||||||
lhs_ptr_inner = lock_guard.deref_mut();
|
lhs_ptr_inner = &mut *lock_guard;
|
||||||
} else {
|
} else {
|
||||||
lhs_ptr_inner = target.as_mut();
|
lhs_ptr_inner = &mut *target;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash = hash_op_assign;
|
let hash = hash_op_assign;
|
||||||
@ -2075,7 +2088,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.inc_operations(state, pos)?;
|
self.inc_operations(state, pos)?;
|
||||||
|
|
||||||
if lhs_ptr.as_ref().is_read_only() {
|
if lhs_ptr.is_read_only() {
|
||||||
// Assignment to constant variable
|
// Assignment to constant variable
|
||||||
EvalAltResult::ErrorAssignmentToConstant(
|
EvalAltResult::ErrorAssignmentToConstant(
|
||||||
lhs_expr.get_variable_name(false).unwrap().to_string(),
|
lhs_expr.get_variable_name(false).unwrap().to_string(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user