Avoid copying indexed value if not necessary.
This commit is contained in:
parent
090217e1cd
commit
4f2350734f
@ -519,12 +519,12 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(prop) = extract_prop_from_setter(fn_name) {
|
if let Some(prop) = extract_prop_from_setter(fn_name) {
|
||||||
let value = args[1].clone();
|
let (arg, value) = args.split_at_mut(0);
|
||||||
|
|
||||||
return match args[0] {
|
return match arg[0] {
|
||||||
// Map property update
|
// Map property update
|
||||||
Dynamic(Union::Map(map)) => {
|
Dynamic(Union::Map(map)) => {
|
||||||
map.insert(prop.to_string(), value);
|
map.insert(prop.to_string(), value[0].clone());
|
||||||
Ok(Dynamic::from_unit())
|
Ok(Dynamic::from_unit())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +588,7 @@ impl Engine<'_> {
|
|||||||
|
|
||||||
// xxx.idx_lhs[idx_expr]
|
// xxx.idx_lhs[idx_expr]
|
||||||
Expr::Index(idx_lhs, idx_expr, op_pos) => {
|
Expr::Index(idx_lhs, idx_expr, op_pos) => {
|
||||||
let value = match idx_lhs.as_ref() {
|
let lhs_value = match idx_lhs.as_ref() {
|
||||||
// xxx.id[idx_expr]
|
// xxx.id[idx_expr]
|
||||||
Expr::Property(id, pos) => {
|
Expr::Property(id, pos) => {
|
||||||
let mut args = [target.get_mut(scope)];
|
let mut args = [target.get_mut(scope)];
|
||||||
@ -596,6 +596,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
// xxx.???[???][idx_expr]
|
// xxx.???[???][idx_expr]
|
||||||
Expr::Index(_, _, _) => {
|
Expr::Index(_, _, _) => {
|
||||||
|
// Chain the indexing
|
||||||
self.get_dot_val_helper(scope, fn_lib, target, idx_lhs, level)?
|
self.get_dot_val_helper(scope, fn_lib, target, idx_lhs, level)?
|
||||||
}
|
}
|
||||||
// Syntax error
|
// Syntax error
|
||||||
@ -607,7 +608,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.get_indexed_value(scope, fn_lib, &value, idx_expr, *op_pos, level)
|
self.get_indexed_value(scope, fn_lib, &lhs_value, idx_expr, *op_pos, level, false)
|
||||||
.map(|(val, _)| val)
|
.map(|(val, _)| val)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,7 +644,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.get_indexed_value(scope, fn_lib, &val, idx_expr, *op_pos, level)
|
self.get_indexed_value(scope, fn_lib, &val, idx_expr, *op_pos, level, false)
|
||||||
.and_then(|(mut val, _)| {
|
.and_then(|(mut val, _)| {
|
||||||
self.get_dot_val_helper(scope, fn_lib, (&mut val).into(), rhs, level)
|
self.get_dot_val_helper(scope, fn_lib, (&mut val).into(), rhs, level)
|
||||||
})
|
})
|
||||||
@ -744,6 +745,7 @@ impl Engine<'_> {
|
|||||||
idx_expr: &Expr,
|
idx_expr: &Expr,
|
||||||
op_pos: Position,
|
op_pos: Position,
|
||||||
level: usize,
|
level: usize,
|
||||||
|
only_index: bool,
|
||||||
) -> Result<(Dynamic, IndexValue), EvalAltResult> {
|
) -> Result<(Dynamic, IndexValue), EvalAltResult> {
|
||||||
let idx_pos = idx_expr.position();
|
let idx_pos = idx_expr.position();
|
||||||
let type_name = self.map_type_name(val.type_name());
|
let type_name = self.map_type_name(val.type_name());
|
||||||
@ -756,13 +758,22 @@ impl Engine<'_> {
|
|||||||
.as_int()
|
.as_int()
|
||||||
.map_err(|_| EvalAltResult::ErrorNumericIndexExpr(idx_expr.position()))?;
|
.map_err(|_| EvalAltResult::ErrorNumericIndexExpr(idx_expr.position()))?;
|
||||||
|
|
||||||
return if index >= 0 {
|
if index >= 0 {
|
||||||
arr.get(index as usize)
|
arr.get(index as usize)
|
||||||
.map(|v| (v.clone(), IndexValue::from_num(index)))
|
.map(|v| {
|
||||||
|
(
|
||||||
|
if only_index {
|
||||||
|
Dynamic::from_unit()
|
||||||
|
} else {
|
||||||
|
v.clone()
|
||||||
|
},
|
||||||
|
IndexValue::from_num(index),
|
||||||
|
)
|
||||||
|
})
|
||||||
.ok_or_else(|| EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos))
|
.ok_or_else(|| EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos))
|
||||||
} else {
|
} else {
|
||||||
Err(EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos))
|
Err(EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos))
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Union::Map(map) => {
|
Union::Map(map) => {
|
||||||
@ -772,12 +783,18 @@ impl Engine<'_> {
|
|||||||
.take_string()
|
.take_string()
|
||||||
.map_err(|_| EvalAltResult::ErrorStringIndexExpr(idx_expr.position()))?;
|
.map_err(|_| EvalAltResult::ErrorStringIndexExpr(idx_expr.position()))?;
|
||||||
|
|
||||||
return Ok((
|
Ok((
|
||||||
map.get(&index)
|
map.get(&index)
|
||||||
.cloned()
|
.map(|v| {
|
||||||
|
if only_index {
|
||||||
|
Dynamic::from_unit()
|
||||||
|
} else {
|
||||||
|
v.clone()
|
||||||
|
}
|
||||||
|
})
|
||||||
.unwrap_or_else(|| Dynamic::from_unit()),
|
.unwrap_or_else(|| Dynamic::from_unit()),
|
||||||
IndexValue::from_str(index),
|
IndexValue::from_str(index),
|
||||||
));
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
Union::Str(s) => {
|
Union::Str(s) => {
|
||||||
@ -787,7 +804,7 @@ impl Engine<'_> {
|
|||||||
.as_int()
|
.as_int()
|
||||||
.map_err(|_| EvalAltResult::ErrorNumericIndexExpr(idx_expr.position()))?;
|
.map_err(|_| EvalAltResult::ErrorNumericIndexExpr(idx_expr.position()))?;
|
||||||
|
|
||||||
return if index >= 0 {
|
if index >= 0 {
|
||||||
s.chars()
|
s.chars()
|
||||||
.nth(index as usize)
|
.nth(index as usize)
|
||||||
.map(|ch| (Dynamic::from_char(ch), IndexValue::from_num(index)))
|
.map(|ch| (Dynamic::from_char(ch), IndexValue::from_num(index)))
|
||||||
@ -800,7 +817,7 @@ impl Engine<'_> {
|
|||||||
index,
|
index,
|
||||||
idx_pos,
|
idx_pos,
|
||||||
))
|
))
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error - cannot be indexed
|
// Error - cannot be indexed
|
||||||
@ -827,7 +844,7 @@ impl Engine<'_> {
|
|||||||
let (ScopeSource { typ, index, .. }, val) =
|
let (ScopeSource { typ, index, .. }, val) =
|
||||||
Self::search_scope(scope, &id, lhs.position())?;
|
Self::search_scope(scope, &id, lhs.position())?;
|
||||||
let (val, idx) =
|
let (val, idx) =
|
||||||
self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level)?;
|
self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level, false)?;
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
Some(ScopeSource {
|
Some(ScopeSource {
|
||||||
@ -843,7 +860,7 @@ impl Engine<'_> {
|
|||||||
// (expr)[idx_expr]
|
// (expr)[idx_expr]
|
||||||
expr => {
|
expr => {
|
||||||
let val = self.eval_expr(scope, fn_lib, expr, level)?;
|
let val = self.eval_expr(scope, fn_lib, expr, level)?;
|
||||||
self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level)
|
self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level, false)
|
||||||
.map(|(val, index)| (None, index, val))
|
.map(|(val, index)| (None, index, val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -951,8 +968,9 @@ impl Engine<'_> {
|
|||||||
let fn_name = make_getter(id);
|
let fn_name = make_getter(id);
|
||||||
self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0)
|
self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0)
|
||||||
.and_then(|val| {
|
.and_then(|val| {
|
||||||
let (_, index) = self
|
let (_, index) = self.get_indexed_value(
|
||||||
.get_indexed_value(scope, fn_lib, &val, idx_expr, *op_pos, level)?;
|
scope, fn_lib, &val, idx_expr, *op_pos, level, true,
|
||||||
|
)?;
|
||||||
|
|
||||||
Self::update_indexed_value(val, index, new_val.0.clone(), new_val.1)
|
Self::update_indexed_value(val, index, new_val.0.clone(), new_val.1)
|
||||||
})
|
})
|
||||||
@ -996,7 +1014,7 @@ impl Engine<'_> {
|
|||||||
self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0)
|
self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0)
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
let (mut value, index) = self.get_indexed_value(
|
let (mut value, index) = self.get_indexed_value(
|
||||||
scope, fn_lib, &v, idx_expr, *op_pos, level,
|
scope, fn_lib, &v, idx_expr, *op_pos, level, false,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let val_pos = new_val.1;
|
let val_pos = new_val.1;
|
||||||
|
Loading…
Reference in New Issue
Block a user