Add Dynamic::NULL to simplify this pointer binding.
This commit is contained in:
@@ -45,7 +45,7 @@ impl Engine {
|
||||
caches: &mut Caches,
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
target: &mut Target,
|
||||
root: (&str, Position),
|
||||
_parent: &Expr,
|
||||
@@ -573,7 +573,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
expr: &Expr,
|
||||
new_val: &mut Option<(Dynamic, &OpAssignment)>,
|
||||
) -> RhaiResult {
|
||||
@@ -630,9 +630,10 @@ impl Engine {
|
||||
|
||||
let obj_ptr = &mut target;
|
||||
let root = (x.3.as_str(), *var_pos);
|
||||
let mut this = Dynamic::NULL;
|
||||
|
||||
self.eval_dot_index_chain_helper(
|
||||
global, caches, lib, level, &mut None, obj_ptr, root, expr, options, rhs,
|
||||
global, caches, lib, level, &mut this, obj_ptr, root, expr, options, rhs,
|
||||
idx_values, chain_type, new_val,
|
||||
)
|
||||
}
|
||||
@@ -664,7 +665,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
expr: &Expr,
|
||||
parent_options: ASTFlags,
|
||||
parent_chain_type: ChainType,
|
||||
|
@@ -416,7 +416,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
node: impl Into<ASTNode<'a>>,
|
||||
) -> RhaiResultOf<()> {
|
||||
if self.debugger.is_some() {
|
||||
@@ -443,7 +443,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
node: impl Into<ASTNode<'a>>,
|
||||
) -> RhaiResultOf<Option<DebuggerStatus>> {
|
||||
if self.debugger.is_some() {
|
||||
@@ -466,7 +466,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
node: impl Into<ASTNode<'a>>,
|
||||
) -> RhaiResultOf<Option<DebuggerStatus>> {
|
||||
let node = node.into();
|
||||
@@ -513,7 +513,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
node: ASTNode<'a>,
|
||||
event: DebuggerEvent,
|
||||
) -> Result<Option<DebuggerStatus>, Box<crate::EvalAltResult>> {
|
||||
|
@@ -8,7 +8,7 @@ use std::prelude::v1::*;
|
||||
/// Context of a script evaluation process.
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct EvalContext<'a, 's, 'ps, 'g, 'c, 't, 'pt> {
|
||||
pub struct EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
|
||||
/// The current [`Engine`].
|
||||
engine: &'a Engine,
|
||||
/// The current [`Scope`].
|
||||
@@ -20,12 +20,12 @@ pub struct EvalContext<'a, 's, 'ps, 'g, 'c, 't, 'pt> {
|
||||
/// The current stack of imported [modules][Module].
|
||||
lib: &'a [SharedModule],
|
||||
/// The current bound `this` pointer, if any.
|
||||
this_ptr: &'t mut Option<&'pt mut Dynamic>,
|
||||
this_ptr: &'t mut Dynamic,
|
||||
/// The current nesting level of function calls.
|
||||
level: usize,
|
||||
}
|
||||
|
||||
impl<'a, 's, 'ps, 'g, 'c, 't, 'pt> EvalContext<'a, 's, 'ps, 'g, 'c, 't, 'pt> {
|
||||
impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
|
||||
/// Create a new [`EvalContext`].
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
@@ -36,7 +36,7 @@ impl<'a, 's, 'ps, 'g, 'c, 't, 'pt> EvalContext<'a, 's, 'ps, 'g, 'c, 't, 'pt> {
|
||||
lib: &'a [SharedModule],
|
||||
level: usize,
|
||||
scope: &'s mut Scope<'ps>,
|
||||
this_ptr: &'t mut Option<&'pt mut Dynamic>,
|
||||
this_ptr: &'t mut Dynamic,
|
||||
) -> Self {
|
||||
Self {
|
||||
engine,
|
||||
@@ -104,8 +104,8 @@ impl<'a, 's, 'ps, 'g, 'c, 't, 'pt> EvalContext<'a, 's, 'ps, 'g, 'c, 't, 'pt> {
|
||||
#[cfg(feature = "internals")]
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn global_runtime_state_mut(&mut self) -> &mut &'g mut GlobalRuntimeState {
|
||||
&mut self.global
|
||||
pub fn global_runtime_state_mut(&mut self) -> &mut GlobalRuntimeState {
|
||||
self.global
|
||||
}
|
||||
/// Get an iterator over the namespaces containing definition of all script-defined functions.
|
||||
#[inline]
|
||||
@@ -121,16 +121,24 @@ impl<'a, 's, 'ps, 'g, 'c, 't, 'pt> EvalContext<'a, 's, 'ps, 'g, 'c, 't, 'pt> {
|
||||
self.lib
|
||||
}
|
||||
/// The current bound `this` pointer, if any.
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn this_ptr(&self) -> Option<&Dynamic> {
|
||||
self.this_ptr.as_ref().map(|v| &**v)
|
||||
if self.this_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(self.this_ptr)
|
||||
}
|
||||
}
|
||||
/// Mutable reference to the current bound `this` pointer, if any.
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn this_ptr_mut(&mut self) -> &mut Option<&'pt mut Dynamic> {
|
||||
self.this_ptr
|
||||
pub fn this_ptr_mut(&mut self) -> Option<&mut Dynamic> {
|
||||
if self.this_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(self.this_ptr)
|
||||
}
|
||||
}
|
||||
/// The current nesting level of function calls.
|
||||
#[inline(always)]
|
||||
|
@@ -54,7 +54,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &'s mut Scope,
|
||||
this_ptr: &'s mut Option<&mut Dynamic>,
|
||||
this_ptr: &'s mut Dynamic,
|
||||
expr: &Expr,
|
||||
) -> RhaiResultOf<(Target<'s>, Position)> {
|
||||
match expr {
|
||||
@@ -140,7 +140,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &'s mut Scope,
|
||||
this_ptr: &'s mut Option<&mut Dynamic>,
|
||||
this_ptr: &'s mut Dynamic,
|
||||
expr: &Expr,
|
||||
) -> RhaiResultOf<(Target<'s>, Position)> {
|
||||
// Make sure that the pointer indirection is taken only when absolutely necessary.
|
||||
@@ -148,10 +148,11 @@ impl Engine {
|
||||
let (index, var_pos) = match expr {
|
||||
// Check if the variable is `this`
|
||||
Expr::Variable(v, None, pos) if v.0.is_none() && v.3 == KEYWORD_THIS => {
|
||||
return this_ptr.as_mut().map_or_else(
|
||||
|| Err(ERR::ErrorUnboundThis(*pos).into()),
|
||||
|val| Ok(((*val).into(), *pos)),
|
||||
)
|
||||
return if this_ptr.is_null() {
|
||||
Err(ERR::ErrorUnboundThis(*pos).into())
|
||||
} else {
|
||||
Ok((this_ptr.into(), *pos))
|
||||
};
|
||||
}
|
||||
_ if global.always_search_scope => (0, expr.start_position()),
|
||||
Expr::Variable(.., Some(i), pos) => (i.get() as usize, *pos),
|
||||
@@ -224,7 +225,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
expr: &Expr,
|
||||
) -> RhaiResult {
|
||||
// Coded this way for better branch prediction.
|
||||
@@ -256,10 +257,11 @@ impl Engine {
|
||||
self.track_operation(global, expr.position())?;
|
||||
|
||||
return if index.is_none() && x.0.is_none() && x.3 == KEYWORD_THIS {
|
||||
this_ptr
|
||||
.as_deref()
|
||||
.cloned()
|
||||
.ok_or_else(|| ERR::ErrorUnboundThis(*var_pos).into())
|
||||
if this_ptr.is_null() {
|
||||
ERR::ErrorUnboundThis(*var_pos).into()
|
||||
} else {
|
||||
Ok(this_ptr.clone())
|
||||
}
|
||||
} else {
|
||||
self.search_namespace(global, caches, lib, level, scope, this_ptr, expr)
|
||||
.map(|(val, ..)| val.take_or_clone())
|
||||
|
@@ -29,7 +29,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
statements: &[Stmt],
|
||||
restore_orig_state: bool,
|
||||
) -> RhaiResult {
|
||||
@@ -203,7 +203,7 @@ impl Engine {
|
||||
lib: &[SharedModule],
|
||||
level: usize,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
this_ptr: &mut Dynamic,
|
||||
stmt: &Stmt,
|
||||
rewind_scope: bool,
|
||||
) -> RhaiResult {
|
||||
@@ -912,8 +912,10 @@ impl Engine {
|
||||
scope: &mut Scope,
|
||||
statements: &[Stmt],
|
||||
) -> RhaiResult {
|
||||
let mut this = Dynamic::NULL;
|
||||
|
||||
self.eval_stmt_block(
|
||||
global, caches, lib, level, scope, &mut None, statements, false,
|
||||
global, caches, lib, level, scope, &mut this, statements, false,
|
||||
)
|
||||
.or_else(|err| match *err {
|
||||
ERR::Return(out, ..) => Ok(out),
|
||||
|
Reference in New Issue
Block a user