Skip to content

Commit

Permalink
Merge pull request #853 from schungx/master
Browse files Browse the repository at this point in the history
Replace update_fn_comments with get_fn_metadata_mut.
  • Loading branch information
schungx authored Mar 25, 2024
2 parents 6619595 + ef2a63d commit 7de8507
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 51 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Bug fixes
* The position of an undefined operation call now points to the operator instead of the first operand.
* The `optimize` command in `rhai-repl` now works properly and cycles through `None`->`Simple`->`Full`.
* `Engine::call_fn_XXX` no longer return errors unnecessarily wrapped in `EvalAltResult::ErrorInFunctionCall`.
* Some tests that panic on 32-bit architecture are fixed.

Deprecated API's
----------------
Expand All @@ -23,6 +24,7 @@ New features
* New options `Engine::set_max_strings_interned` and `Engine::max_strings_interned` are added to limit the maximum number of strings interned in the `Engine`'s string interner.
* A new advanced callback, `Engine::on_invalid_array_index`, is added (gated under the `internals` feature) to handle access to missing properties in object maps.
* A new advanced callback, `Engine::on_missing_map_property`, is added (gated under the `internals` feature) to handle out-of-bound index into arrays.
* Doc-comments are now automatically added to function registrations and custom types via the `CustomType` derive macro.

Enhancements
------------
Expand Down
7 changes: 7 additions & 0 deletions codegen/ui_tests/rhai_mod_inner_cfg_false.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@ error[E0433]: failed to resolve: could not find `test_mod` in `test_module`
|
24 | if test_module::test_mod::test_fn(n) {
| ^^^^^^^^ could not find `test_mod` in `test_module`
|
note: found an item that was configured out
--> ui_tests/rhai_mod_inner_cfg_false.rs:12:13
|
12 | pub mod test_mod {
| ^^^^^^^^
= note: the item is gated behind the `unset_feature` feature
47 changes: 30 additions & 17 deletions src/api/build_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
use crate::func::SendSync;
use crate::module::FuncMetadata;
use crate::packages::string_basic::{FUNC_TO_DEBUG, FUNC_TO_STRING};
use crate::FuncRegistration;
use crate::{types::dynamic::Variant, Engine, Identifier, RhaiNativeFunc};
use crate::types::dynamic::Variant;
use crate::{Engine, FuncRegistration, Identifier, RhaiNativeFunc, StaticVec};
use std::marker::PhantomData;

#[cfg(feature = "no_std")]
Expand Down Expand Up @@ -104,7 +104,7 @@ impl Engine {
pub struct TypeBuilder<'a, T: Variant + Clone> {
engine: &'a mut Engine,
/// Keep the latest registered function(s) in cache to add additional metadata.
hashes: Vec<u64>,
hashes: StaticVec<u64>,
_marker: PhantomData<T>,
}

Expand All @@ -114,7 +114,7 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> {
fn new(engine: &'a mut Engine) -> Self {
Self {
engine,
hashes: vec![],
hashes: StaticVec::new_const(),
_marker: PhantomData,
}
}
Expand Down Expand Up @@ -155,7 +155,8 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
) -> &mut Self {
let FuncMetadata { hash, .. } =
FuncRegistration::new(FUNC_TO_STRING).register_into_engine(self.engine, on_print);
self.hashes = vec![*hash];
self.hashes.clear();
self.hashes.push(*hash);
self
}

Expand All @@ -167,7 +168,8 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
) -> &mut Self {
let FuncMetadata { hash, .. } =
FuncRegistration::new(FUNC_TO_DEBUG).register_into_engine(self.engine, on_debug);
self.hashes = vec![*hash];
self.hashes.clear();
self.hashes.push(*hash);
self
}

Expand All @@ -180,19 +182,22 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
) -> &mut Self {
let FuncMetadata { hash, .. } =
FuncRegistration::new(name).register_into_engine(self.engine, method);
self.hashes = vec![*hash];
self.hashes.clear();
self.hashes.push(*hash);
self
}

/// Add comments to the last registered function.
/// Available under the metadata feature only.
/// _(metadata)_ Add comments to the last registered function.
/// Available under the `metadata` feature only.
#[cfg(feature = "metadata")]
#[inline(always)]
pub fn and_comments(&mut self, comments: &[&str]) -> &mut Self {
let module = self.engine.global_namespace_mut();

for hash in &self.hashes {
module.update_fn_comments(*hash, comments);
for &hash in &self.hashes {
if let Some(f) = module.get_fn_metadata_mut(hash) {
f.comments = comments.into_iter().map(|&s| s.into()).collect();
}
}

self
Expand Down Expand Up @@ -228,7 +233,8 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
) -> &mut Self {
let FuncMetadata { hash, .. } =
FuncRegistration::new_getter(name).register_into_engine(self.engine, get_fn);
self.hashes = vec![*hash];
self.hashes.clear();
self.hashes.push(*hash);

self
}
Expand All @@ -244,7 +250,8 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
) -> &mut Self {
let FuncMetadata { hash, .. } =
FuncRegistration::new_setter(name).register_into_engine(self.engine, set_fn);
self.hashes = vec![*hash];
self.hashes.clear();
self.hashes.push(*hash);

self
}
Expand Down Expand Up @@ -273,7 +280,9 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
let hash_2 = FuncRegistration::new_setter(&name)
.register_into_engine(self.engine, set_fn)
.hash;
self.hashes = vec![hash_1, hash_2];
self.hashes.clear();
self.hashes.push(hash_1);
self.hashes.push(hash_2);

self
}
Expand All @@ -298,7 +307,8 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
) -> &mut Self {
let FuncMetadata { hash, .. } =
FuncRegistration::new_index_getter().register_into_engine(self.engine, get_fn);
self.hashes = vec![*hash];
self.hashes.clear();
self.hashes.push(*hash);

self
}
Expand All @@ -318,7 +328,8 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
) -> &mut Self {
let FuncMetadata { hash, .. } =
FuncRegistration::new_index_setter().register_into_engine(self.engine, set_fn);
self.hashes = vec![*hash];
self.hashes.clear();
self.hashes.push(*hash);

self
}
Expand All @@ -345,7 +356,9 @@ impl<T: Variant + Clone> TypeBuilder<'_, T> {
let hash_2 = FuncRegistration::new_index_setter()
.register_into_engine(self.engine, set_fn)
.hash;
self.hashes = vec![hash_1, hash_2];
self.hashes.clear();
self.hashes.push(hash_1);
self.hashes.push(hash_2);

self
}
Expand Down
1 change: 0 additions & 1 deletion src/bin/rhai-repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,6 @@ fn main() {
.compile_with_scope(&scope, &input)
.map_err(Into::into)
.and_then(|r| {
println!("AST: {r:#?}");
#[cfg(not(feature = "no_optimize"))]
{
ast_u = r.clone();
Expand Down
24 changes: 7 additions & 17 deletions src/eval/chaining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,29 +482,19 @@ impl Engine {
}
// Short-circuit for indexing with literal: {expr}[1]
#[cfg(not(feature = "no_index"))]
(_, ChainType::Indexing) if rhs.is_constant() => {
idx_values.push(rhs.get_literal_value().unwrap())
}
#[cfg(not(feature = "no_index"))]
(Expr::FnCall(fnc, _), ChainType::Indexing)
if fnc.op_token == Some(crate::tokenizer::Token::InclusiveRange)
|| fnc.op_token == Some(crate::tokenizer::Token::ExclusiveRange) =>
{
(_, ChainType::Indexing) if rhs.get_literal_value().is_some() => {
idx_values.push(rhs.get_literal_value().unwrap())
}
// Short-circuit for simple method call: {expr}.func()
#[cfg(not(feature = "no_object"))]
(Expr::MethodCall(x, ..), ChainType::Dotting) if x.args.is_empty() => (),
// All other patterns - evaluate the arguments chain
_ => self.eval_dot_index_chain_arguments(
global,
caches,
scope,
this_ptr.as_deref_mut(),
expr,
rhs,
idx_values,
)?,
_ => {
let this_ptr = this_ptr.as_deref_mut();
self.eval_dot_index_chain_arguments(
global, caches, scope, this_ptr, expr, rhs, idx_values,
)?
}
}

match (lhs, new_val) {
Expand Down
20 changes: 7 additions & 13 deletions src/module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1483,20 +1483,14 @@ impl Module {
self
}

/// _(metadata)_ Update the comments of a registered function.
/// Exported under the `metadata` feature only.
#[cfg(feature = "metadata")]
/// Get a registered function's metadata.
#[inline]
pub(crate) fn update_fn_comments<S: AsRef<str>>(
&mut self,
hash_fn: u64,
comments: impl IntoIterator<Item = S>,
) -> &mut Self {
if let Some((_, f)) = self.functions.as_mut().and_then(|m| m.get_mut(&hash_fn)) {
f.comments = comments.into_iter().map(|s| s.as_ref().into()).collect();
}

self
#[allow(dead_code)]
pub(crate) fn get_fn_metadata_mut(&mut self, hash_fn: u64) -> Option<&mut FuncMetadata> {
self.functions
.as_mut()
.and_then(|m| m.get_mut(&hash_fn))
.map(|(_, f)| f.as_mut())
}

/// Remap type ID.
Expand Down
35 changes: 32 additions & 3 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,42 @@ fn check_struct_sizes() {
));
const WORD_SIZE: usize = size_of::<usize>();

assert_eq!(size_of::<Dynamic>(), if PACKED { 8 } else { 16 });
assert_eq!(size_of::<Option<Dynamic>>(), if PACKED { 8 } else { 16 });
assert_eq!(
size_of::<Dynamic>(),
if PACKED {
8
} else if IS_32_BIT {
12
} else {
16
}
);
assert_eq!(
size_of::<Option<Dynamic>>(),
if PACKED {
8
} else if IS_32_BIT {
12
} else {
16
}
);
assert_eq!(
size_of::<Position>(),
if cfg!(feature = "no_position") { 0 } else { 4 }
);
assert_eq!(size_of::<tokenizer::Token>(), 2 * WORD_SIZE);
assert_eq!(
size_of::<tokenizer::Token>(),
if IS_32_BIT {
if cfg!(feature = "only_i32") {
2 * WORD_SIZE
} else {
3 * WORD_SIZE
}
} else {
2 * WORD_SIZE
}
);
assert_eq!(size_of::<ast::Expr>(), if PACKED { 12 } else { 16 });
assert_eq!(size_of::<Option<ast::Expr>>(), if PACKED { 12 } else { 16 });
assert_eq!(size_of::<ast::Stmt>(), if IS_32_BIT { 12 } else { 16 });
Expand Down

0 comments on commit 7de8507

Please sign in to comment.