Fix no_index build.

This commit is contained in:
Stephen Chung 2021-05-18 21:38:09 +08:00
parent dc9b4d7f4d
commit 2ade56fd94
3 changed files with 68 additions and 54 deletions

View File

@ -1154,7 +1154,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, idx_val, idx_pos, false, is_ref, true, level, mods, state, lib, target, idx_val, idx_pos, false, true, level,
)?; )?;
let rhs_chain = rhs_chain.unwrap(); let rhs_chain = rhs_chain.unwrap();
@ -1173,7 +1173,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, idx_val, pos, true, is_ref, false, level, mods, state, lib, target, idx_val, pos, true, false, level,
) { ) {
// Indexed value is a reference - update directly // Indexed value is a reference - update directly
Ok(obj_ptr) => { Ok(obj_ptr) => {
@ -1193,7 +1193,6 @@ impl Engine {
}, },
}; };
#[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.type_name(); let val_type_name = target.type_name();
let ((_, val_pos), _) = new_val; let ((_, val_pos), _) = new_val;
@ -1228,7 +1227,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, idx_val, pos, false, is_ref, true, level, mods, state, lib, target, idx_val, pos, false, true, level,
) )
.map(|v| (v.take_or_clone(), false)) .map(|v| (v.take_or_clone(), false))
} }
@ -1259,7 +1258,7 @@ impl Engine {
let (name, pos) = &x.2; let (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, index, *pos, true, is_ref, false, level, mods, state, lib, target, index, *pos, true, 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(
@ -1272,7 +1271,7 @@ impl Engine {
let (name, pos) = &x.2; let (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, index, *pos, false, is_ref, false, level, mods, state, lib, target, index, *pos, false, false, level,
)?; )?;
Ok((val.take_or_clone(), false)) Ok((val.take_or_clone(), false))
@ -1285,10 +1284,29 @@ impl Engine {
if op_info.is_some() { if op_info.is_some() {
let hash = FnCallHashes::from_native(*hash_get); let hash = FnCallHashes::from_native(*hash_get);
let mut args = [target.as_mut()]; let mut args = [target.as_mut()];
let (mut orig_val, _) = self.exec_fn_call( let (mut orig_val, _) = self
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos, .exec_fn_call(
None, level, mods, state, lib, getter, hash, &mut args, is_ref, true, *pos,
)?; None, level,
)
.or_else(|err| match *err {
// Try an indexer if property does not exist
EvalAltResult::ErrorDotExpr(_, _) => {
let prop = name.into();
self.get_indexed_mut(
mods, state, lib, target, prop, *pos, false, true,
level,
)
.map(|v| (v.take_or_clone(), false))
.map_err(
|idx_err| match *idx_err {
EvalAltResult::ErrorIndexingType(_, _) => err,
_ => idx_err,
},
)
}
_ => Err(err),
})?;
let obj_ptr = (&mut orig_val).into(); let obj_ptr = (&mut orig_val).into();
self.eval_op_assignment( self.eval_op_assignment(
mods, state, lib, op_info, op_pos, obj_ptr, root, new_val, new_pos, mods, state, lib, op_info, op_pos, obj_ptr, root, new_val, new_pos,
@ -1341,8 +1359,7 @@ impl Engine {
EvalAltResult::ErrorDotExpr(_, _) => { EvalAltResult::ErrorDotExpr(_, _) => {
let prop = name.into(); let prop = name.into();
self.get_indexed_mut( self.get_indexed_mut(
mods, state, lib, target, prop, *pos, false, is_ref, true, mods, state, lib, target, prop, *pos, false, true, level,
level,
) )
.map(|v| (v.take_or_clone(), false)) .map(|v| (v.take_or_clone(), false))
.map_err(|idx_err| { .map_err(|idx_err| {
@ -1364,8 +1381,7 @@ impl Engine {
let (name, pos) = &p.2; let (name, pos) = &p.2;
let index = name.into(); let index = name.into();
self.get_indexed_mut( self.get_indexed_mut(
mods, state, lib, target, index, *pos, false, is_ref, true, mods, state, lib, target, index, *pos, false, true, level,
level,
)? )?
} }
// {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr // {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr
@ -1414,8 +1430,8 @@ impl Engine {
EvalAltResult::ErrorDotExpr(_, _) => { EvalAltResult::ErrorDotExpr(_, _) => {
let prop = name.into(); let prop = name.into();
self.get_indexed_mut( self.get_indexed_mut(
mods, state, lib, target, prop, *pos, false, mods, state, lib, target, prop, *pos, false, true,
is_ref, true, level, level,
) )
.map(|v| (v.take_or_clone(), false)) .map(|v| (v.take_or_clone(), false))
.map_err( .map_err(
@ -1717,16 +1733,15 @@ impl Engine {
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
fn get_indexed_mut<'t>( fn get_indexed_mut<'t>(
&self, &self,
_mods: &mut Imports, mods: &mut Imports,
state: &mut State, state: &mut State,
_lib: &[&Module], lib: &[&Module],
target: &'t mut Dynamic, target: &'t mut Dynamic,
mut _idx: Dynamic, mut idx: Dynamic,
idx_pos: Position, idx_pos: Position,
_create: bool, _create: bool,
_is_ref: bool, indexers: bool,
_indexers: bool, level: usize,
_level: usize,
) -> Result<Target<'t>, Box<EvalAltResult>> { ) -> Result<Target<'t>, Box<EvalAltResult>> {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
self.inc_operations(state, Position::NONE)?; self.inc_operations(state, Position::NONE)?;
@ -1735,7 +1750,7 @@ impl Engine {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Dynamic(Union::Array(arr, _, _)) => { Dynamic(Union::Array(arr, _, _)) => {
// val_array[idx] // val_array[idx]
let index = _idx let index = idx
.as_int() .as_int()
.map_err(|err| self.make_type_mismatch_err::<crate::INT>(err, idx_pos))?; .map_err(|err| self.make_type_mismatch_err::<crate::INT>(err, idx_pos))?;
@ -1777,8 +1792,8 @@ impl Engine {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
Dynamic(Union::Map(map, _, _)) => { Dynamic(Union::Map(map, _, _)) => {
// val_map[idx] // val_map[idx]
let index = &*_idx.read_lock::<ImmutableString>().ok_or_else(|| { let index = &*idx.read_lock::<ImmutableString>().ok_or_else(|| {
self.make_type_mismatch_err::<ImmutableString>(_idx.type_name(), idx_pos) self.make_type_mismatch_err::<ImmutableString>(idx.type_name(), idx_pos)
})?; })?;
if _create && !map.contains_key(index.as_str()) { if _create && !map.contains_key(index.as_str()) {
@ -1794,7 +1809,7 @@ impl Engine {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Dynamic(Union::Str(s, _, _)) => { Dynamic(Union::Str(s, _, _)) => {
// val_string[idx] // val_string[idx]
let index = _idx let index = idx
.as_int() .as_int()
.map_err(|err| self.make_type_mismatch_err::<crate::INT>(err, idx_pos))?; .map_err(|err| self.make_type_mismatch_err::<crate::INT>(err, idx_pos))?;
@ -1825,15 +1840,16 @@ impl Engine {
Ok(Target::StringChar(target, offset, ch.into())) Ok(Target::StringChar(target, offset, ch.into()))
} }
#[cfg(not(feature = "no_index"))] _ if indexers => {
_ if _indexers => { let args = &mut [target, &mut idx];
let args = &mut [target, &mut _idx]; let hash_get = FnCallHashes::from_native(crate::calc_fn_hash(
let hash_get = std::iter::empty(),
FnCallHashes::from_native(calc_fn_hash(std::iter::empty(), FN_IDX_GET, 2)); FN_IDX_GET,
2,
));
self.exec_fn_call( self.exec_fn_call(
_mods, state, _lib, FN_IDX_GET, hash_get, args, _is_ref, true, idx_pos, None, mods, state, lib, FN_IDX_GET, hash_get, args, true, true, idx_pos, None, level,
_level,
) )
.map(|(v, _)| v.into()) .map(|(v, _)| v.into())
} }

View File

@ -371,7 +371,7 @@ impl Engine {
match fn_name { match fn_name {
// index getter function not found? // index getter function not found?
#[cfg(not(feature = "no_index"))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
crate::engine::FN_IDX_GET => { crate::engine::FN_IDX_GET => {
assert!(args.len() == 2); assert!(args.len() == 2);
@ -383,7 +383,7 @@ impl Engine {
} }
// index setter function not found? // index setter function not found?
#[cfg(not(feature = "no_index"))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
crate::engine::FN_IDX_SET => { crate::engine::FN_IDX_SET => {
assert!(args.len() == 3); assert!(args.len() == 3);

View File

@ -46,28 +46,26 @@ fn test_get_set() -> Result<(), Box<EvalAltResult>> {
assert_eq!(engine.eval::<INT>("let a = new_ts(); a.x.add(); a.x")?, 42); assert_eq!(engine.eval::<INT>("let a = new_ts(); a.x.add(); a.x")?, 42);
assert_eq!(engine.eval::<INT>("let a = new_ts(); a.y.add(); a.y")?, 0); assert_eq!(engine.eval::<INT>("let a = new_ts(); a.y.add(); a.y")?, 0);
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] engine.register_indexer_get_set(
{ |value: &mut TestStruct, index: &str| value.array[index.len()],
engine.register_indexer_get_set( |value: &mut TestStruct, index: &str, new_val: INT| value.array[index.len()] = new_val,
|value: &mut TestStruct, index: &str| value.array[index.len()], );
|value: &mut TestStruct, index: &str, new_val: INT| value.array[index.len()] = new_val,
);
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
assert_eq!(engine.eval::<INT>(r#"let a = new_ts(); a["abc"]"#)?, 4); assert_eq!(engine.eval::<INT>(r#"let a = new_ts(); a["abc"]"#)?, 4);
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
assert_eq!( assert_eq!(
engine.eval::<INT>(r#"let a = new_ts(); a["abc"] = 42; a["abc"]"#)?, engine.eval::<INT>(r#"let a = new_ts(); a["abc"] = 42; a["abc"]"#)?,
42 42
); );
assert_eq!(engine.eval::<INT>(r"let a = new_ts(); a.abc")?, 4);
assert_eq!(
engine.eval::<INT>(r"let a = new_ts(); a.abc = 42; a.abc")?,
42
);
assert_eq!(engine.eval::<INT>(r"let a = new_ts(); a.abc")?, 4);
assert_eq!(
engine.eval::<INT>(r"let a = new_ts(); a.abc = 42; a.abc")?,
42
);
}
Ok(()) Ok(())
} }