Add Dynamic::NULL to simplify this pointer binding.

This commit is contained in:
Stephen Chung
2022-11-08 16:16:42 +08:00
parent 6053aa1641
commit 8f128f37f0
16 changed files with 126 additions and 77 deletions

View File

@@ -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,

View File

@@ -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>> {

View File

@@ -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)]

View File

@@ -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())

View File

@@ -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),