From 0ae4d14a626aa62db4be1012de7a084de9e1aeab Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 18 Dec 2021 15:37:20 +0800 Subject: [PATCH] Move BLOB concat and push to builtin. --- src/func/builtin.rs | 61 +++++++++++++++++++++++++++++++++++-- src/packages/array_basic.rs | 2 +- src/packages/blob_basic.rs | 17 ++--------- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/func/builtin.rs b/src/func/builtin.rs index 38a73af8..4ab2f938 100644 --- a/src/func/builtin.rs +++ b/src/func/builtin.rs @@ -282,15 +282,37 @@ pub fn get_builtin_binary_op_fn( if type2 == TypeId::of::() { return match op { OP_CONTAINS => Some(|_, args| { - let range = &*args[0].read_lock::().expect(BUILTIN); + let blob = &*args[0].read_lock::().expect(BUILTIN); let x = (args[1].as_int().expect("`INT`") & 0x000000ff) as u8; - Ok(range.contains(&x).into()) + Ok(blob.contains(&x).into()) }), _ => None, }; } if type1 == type2 { return match op { + "+" => Some(|_, args| { + let blob1 = &*args[0].read_lock::().expect(BUILTIN); + let blob2 = &*args[1].read_lock::().expect(BUILTIN); + let result = if blob1.is_empty() { + if blob2.is_empty() { + Blob::new() + } else { + blob2.clone() + } + } else { + if blob2.is_empty() { + blob1.clone() + } else { + let mut blob = Blob::with_capacity(blob1.len() + blob2.len()); + blob.extend_from_slice(blob1); + blob.extend_from_slice(blob2); + blob + } + }; + + Ok(Dynamic::from_blob(result)) // do not use result.into() because it'll convert into an Array + }), "==" => Some(impl_op!(Blob == Blob)), "!=" => Some(impl_op!(Blob != Blob)), _ => None, @@ -652,6 +674,20 @@ pub fn get_builtin_op_assignment_fn( _ => None, }; } + // Blob op= int + #[cfg(not(feature = "no_index"))] + if types_pair == (TypeId::of::(), TypeId::of::()) { + use crate::Blob; + + return match op { + "+=" => Some(|_, args| { + let x = (args[1].as_int().expect("`INT`") & 0x000000ff) as u8; + let mut blob = args[0].write_lock::().expect(BUILTIN); + Ok(blob.push(x).into()) + }), + _ => None, + }; + } // No built-in op-assignments for different types. if type2 != type1 { @@ -734,5 +770,26 @@ pub fn get_builtin_op_assignment_fn( }; } + #[cfg(not(feature = "no_index"))] + if type1 == TypeId::of::() { + use crate::Blob; + + return match op { + "+=" => Some(|_, args| { + let blob2 = std::mem::take(args[1]).cast::(); + let mut blob1 = args[0].write_lock::().expect(BUILTIN); + if !blob2.is_empty() { + if blob1.is_empty() { + *blob1 = blob2; + } else { + blob1.extend_from_slice(&blob2); + } + } + Ok(Dynamic::UNIT) + }), + _ => None, + }; + } + None } diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 9ceeda20..cc1f68db 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -172,7 +172,7 @@ mod array_functions { .checked_abs() .map_or(0, |n| arr_len - (n as usize).min(arr_len)) } else if start as usize >= array.len() { - array.extend(replace.into_iter()); + array.extend(replace); return; } else { start as usize diff --git a/src/packages/blob_basic.rs b/src/packages/blob_basic.rs index 8d63a2a7..2adf04f8 100644 --- a/src/packages/blob_basic.rs +++ b/src/packages/blob_basic.rs @@ -61,12 +61,12 @@ mod blob_functions { pub fn len(blob: &mut Blob) -> INT { blob.len() as INT } - #[rhai_fn(name = "push", name = "+=")] + #[rhai_fn(name = "push")] pub fn push(blob: &mut Blob, item: INT) { let item = (item & 0x00ff) as u8; blob.push(item); } - #[rhai_fn(name = "append", name = "+=")] + #[rhai_fn(name = "append")] pub fn append(blob: &mut Blob, y: Blob) { if !y.is_empty() { if blob.is_empty() { @@ -76,17 +76,6 @@ mod blob_functions { } } } - #[rhai_fn(name = "+")] - pub fn concat(mut blob: Blob, y: Blob) -> Blob { - if !y.is_empty() { - if blob.is_empty() { - blob = y; - } else { - blob.extend(y); - } - } - blob - } pub fn insert(blob: &mut Blob, position: INT, item: INT) { let item = (item & 0x00ff) as u8; @@ -211,7 +200,7 @@ mod blob_functions { .checked_abs() .map_or(0, |n| blob_len - (n as usize).min(blob_len)) } else if start as usize >= blob_len { - blob.extend(replace.into_iter()); + blob.extend(replace); return; } else { start as usize