Remove hashing of the entire script by making Expr and Stmt Hash.

This commit is contained in:
Stephen Chung
2021-01-04 11:58:24 +08:00
parent e2a47b2a65
commit cf9d35166d
6 changed files with 191 additions and 112 deletions

View File

@@ -41,8 +41,6 @@ type FunctionsLib = HashMap<NonZeroU64, ScriptFnDef, StraightHasherBuilder>;
struct ParseState<'e> {
/// Reference to the scripting [`Engine`].
engine: &'e Engine,
/// Hash that uniquely identifies a script.
script_hash: u64,
/// Interned strings.
strings: HashMap<String, ImmutableString>,
/// Encapsulates a local stack with variable names to simulate an actual runtime scope.
@@ -75,7 +73,6 @@ impl<'e> ParseState<'e> {
#[inline(always)]
pub fn new(
engine: &'e Engine,
script_hash: u64,
#[cfg(not(feature = "unchecked"))] max_expr_depth: usize,
#[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_function"))]
@@ -83,7 +80,6 @@ impl<'e> ParseState<'e> {
) -> Self {
Self {
engine,
script_hash,
#[cfg(not(feature = "unchecked"))]
max_expr_depth,
#[cfg(not(feature = "unchecked"))]
@@ -919,7 +915,7 @@ fn parse_switch(
Ok(Stmt::Switch(
item,
Box::new((final_table, def_stmt)),
Box::new((final_table.into(), def_stmt)),
settings.pos,
))
}
@@ -956,7 +952,7 @@ fn parse_primary(
},
#[cfg(not(feature = "no_float"))]
Token::FloatConstant(x) => {
let x = *x;
let x = (*x).into();
input.next().unwrap();
Expr::FloatConstant(x, settings.pos)
}
@@ -986,7 +982,6 @@ fn parse_primary(
Token::Pipe | Token::Or if settings.allow_anonymous_fn => {
let mut new_state = ParseState::new(
state.engine,
state.script_hash,
#[cfg(not(feature = "unchecked"))]
state.max_function_expr_depth,
#[cfg(not(feature = "unchecked"))]
@@ -1284,7 +1279,7 @@ fn parse_unary(
.map(|i| Expr::IntegerConstant(i, pos))
.or_else(|| {
#[cfg(not(feature = "no_float"))]
return Some(Expr::FloatConstant(-(num as FLOAT), pos));
return Some(Expr::FloatConstant((-(num as FLOAT)).into(), pos));
#[cfg(feature = "no_float")]
return None;
})
@@ -1292,7 +1287,7 @@ fn parse_unary(
// Negative float
#[cfg(not(feature = "no_float"))]
Expr::FloatConstant(x, pos) => Ok(Expr::FloatConstant(-x, pos)),
Expr::FloatConstant(x, pos) => Ok(Expr::FloatConstant((-(*x)).into(), pos)),
// Call negative function
expr => {
@@ -1998,14 +1993,7 @@ fn parse_custom_syntax(
}
}
Ok(Expr::Custom(
Box::new(CustomExpr {
keywords,
func: syntax.func.clone(),
tokens,
}),
pos,
))
Ok(Expr::Custom(Box::new(CustomExpr { keywords, tokens }), pos))
}
/// Parse an expression.
@@ -2600,7 +2588,6 @@ fn parse_stmt(
(Token::Fn, pos) => {
let mut new_state = ParseState::new(
state.engine,
state.script_hash,
#[cfg(not(feature = "unchecked"))]
state.max_function_expr_depth,
#[cfg(not(feature = "unchecked"))]
@@ -3009,10 +2996,10 @@ fn parse_anon_fn(
params.into_iter().map(|(v, _)| v).collect()
};
// Create unique function name by hashing the script hash plus the position
// Create unique function name by hashing the script body plus the parameters.
let hasher = &mut get_hasher();
state.script_hash.hash(hasher);
settings.pos.hash(hasher);
params.iter().for_each(|p| p.as_str().hash(hasher));
body.hash(hasher);
let hash = hasher.finish();
let fn_name: ImmutableString = format!("{}{:016x}", crate::engine::FN_ANONYMOUS, hash).into();
@@ -3045,7 +3032,6 @@ fn parse_anon_fn(
impl Engine {
pub(crate) fn parse_global_expr(
&self,
script_hash: u64,
input: &mut TokenStream,
scope: &Scope,
optimization_level: OptimizationLevel,
@@ -3053,7 +3039,6 @@ impl Engine {
let mut functions = Default::default();
let mut state = ParseState::new(
self,
script_hash,
#[cfg(not(feature = "unchecked"))]
self.max_expr_depth(),
#[cfg(not(feature = "unchecked"))]
@@ -3095,14 +3080,12 @@ impl Engine {
/// Parse the global level statements.
fn parse_global_level(
&self,
script_hash: u64,
input: &mut TokenStream,
) -> Result<(Vec<Stmt>, Vec<ScriptFnDef>), ParseError> {
let mut statements = Vec::with_capacity(16);
let mut functions = HashMap::with_capacity_and_hasher(16, StraightHasherBuilder);
let mut state = ParseState::new(
self,
script_hash,
#[cfg(not(feature = "unchecked"))]
self.max_expr_depth(),
#[cfg(not(feature = "unchecked"))]
@@ -3165,12 +3148,11 @@ impl Engine {
#[inline(always)]
pub(crate) fn parse(
&self,
script_hash: u64,
input: &mut TokenStream,
scope: &Scope,
optimization_level: OptimizationLevel,
) -> Result<AST, ParseError> {
let (statements, lib) = self.parse_global_level(script_hash, input)?;
let (statements, lib) = self.parse_global_level(input)?;
Ok(
// Optimize AST