From fa8e2e638b69370e227a4297d91f60344f2bc659 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 23 Feb 2022 15:43:27 +0800 Subject: [PATCH] Fix bug. --- src/func/register.rs | 62 +++++++++++++++++++++++--------------------- src/module/mod.rs | 9 ++++--- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/src/func/register.rs b/src/func/register.rs index eab4000d..289dd8db 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -85,22 +85,32 @@ pub trait RegisterNativeFunction { fn return_type_name() -> &'static str; } -#[inline] -#[must_use] -fn is_setter(_fn_name: &str) -> bool { - #[cfg(not(feature = "no_object"))] - if _fn_name.starts_with(crate::engine::FN_SET) { - return true; - } - #[cfg(not(feature = "no_index"))] - if _fn_name.starts_with(crate::engine::FN_IDX_SET) { - return true; - } - false -} - const EXPECT_ARGS: &str = "arguments"; +macro_rules! check_constant { + ($ctx:ident, $args:ident) => { + #[cfg(any(not(feature = "no_object"), not(feature = "no_index")))] + { + let args_len = $args.len(); + + if args_len > 0 && $args[0].is_read_only() { + let deny = match $ctx.fn_name() { + #[cfg(not(feature = "no_object"))] + f if args_len == 2 && f.starts_with(crate::engine::FN_SET) => true, + #[cfg(not(feature = "no_index"))] + crate::engine::FN_IDX_SET if args_len == 3 => true, + _ => false, + }; + if deny { + return Err( + ERR::ErrorAssignmentToConstant(String::new(), Position::NONE).into(), + ); + } + } + } + }; +} + macro_rules! def_register { () => { def_register!(imp from_pure :); @@ -124,11 +134,9 @@ macro_rules! def_register { #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::() } #[inline(always)] fn into_callable_function(self) -> CallableFunction { CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| { - if args.len() == 2 && args[0].is_read_only() && is_setter(ctx.fn_name()) { - return Err(ERR::ErrorAssignmentToConstant(String::new(), Position::NONE).into()); - } - // The arguments are assumed to be of the correct number and types! + check_constant!(ctx, args); + let mut _drain = args.iter_mut(); $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* @@ -152,11 +160,9 @@ macro_rules! def_register { #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::() } #[inline(always)] fn into_callable_function(self) -> CallableFunction { CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| { - if args.len() == 2 && args[0].is_read_only() && is_setter(ctx.fn_name()) { - return Err(ERR::ErrorAssignmentToConstant(String::new(), Position::NONE).into()); - } - // The arguments are assumed to be of the correct number and types! + check_constant!(ctx, args); + let mut _drain = args.iter_mut(); $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* @@ -180,11 +186,9 @@ macro_rules! def_register { #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::>() } #[inline(always)] fn into_callable_function(self) -> CallableFunction { CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| { - if args.len() == 2 && args[0].is_read_only() && is_setter(ctx.fn_name()) { - return Err(ERR::ErrorAssignmentToConstant(String::new(), Position::NONE).into()); - } - // The arguments are assumed to be of the correct number and types! + check_constant!(ctx, args); + let mut _drain = args.iter_mut(); $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* @@ -205,11 +209,9 @@ macro_rules! def_register { #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::>() } #[inline(always)] fn into_callable_function(self) -> CallableFunction { CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| { - if args.len() == 2 && args[0].is_read_only() && is_setter(ctx.fn_name()) { - return Err(ERR::ErrorAssignmentToConstant(String::new(), Position::NONE).into()); - } - // The arguments are assumed to be of the correct number and types! + check_constant!(ctx, args); + let mut _drain = args.iter_mut(); $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* diff --git a/src/module/mod.rs b/src/module/mod.rs index 4b241288..8139a155 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -1670,9 +1670,12 @@ impl Module { } /// Create a new [`Module`] by evaluating an [`AST`][crate::AST]. /// - /// The entire [`AST`][crate::AST] is encapsulated into each function, allowing functions - /// to cross-call each other. Functions in the global namespace, plus all functions - /// defined in the [`Module`], are _merged_ into a _unified_ namespace before each call. + /// The entire [`AST`][crate::AST] is encapsulated into each function, allowing functions to + /// cross-call each other. + /// + /// Functions in the global namespace, plus all functions defined in the [`Module`], are + /// _merged_ into a _unified_ namespace before each call. + /// /// Therefore, all functions will be found. #[cfg(not(feature = "no_module"))] pub(crate) fn eval_ast_as_new_raw(