From 2214a62f1f753594395132ee80150525cc8f0fd5 Mon Sep 17 00:00:00 2001 From: Ryan Daum Date: Fri, 30 Aug 2024 00:04:25 -0400 Subject: [PATCH] Move variant construction around a bit * Var now holds the raw Bytes and constructs the Variant on demand * The hope being this makes it faster/easier to move in and out of storage * The inside of the Variant now holds an Arc< for non-Scalar values In the future I might make it so Var can contain either a "materialized" Variant, or the Bytes. --- crates/compiler/src/codegen.rs | 22 +-- crates/console-host/src/main.rs | 2 +- crates/daemon/src/rpc_server.rs | 2 +- .../db-wiredtiger/src/bindings/connection.rs | 2 +- crates/db/src/db_worldstate.rs | 8 +- crates/kernel/src/builtins/bf_list_sets.rs | 4 +- crates/kernel/src/builtins/bf_num.rs | 22 +-- crates/kernel/src/builtins/bf_objects.rs | 33 ++-- crates/kernel/src/builtins/bf_properties.rs | 20 +-- crates/kernel/src/builtins/bf_server.rs | 44 +++--- crates/kernel/src/builtins/bf_strings.rs | 6 +- crates/kernel/src/builtins/bf_values.rs | 20 +-- crates/kernel/src/builtins/bf_verbs.rs | 76 +++++----- crates/kernel/src/tasks/scheduler.rs | 14 +- crates/kernel/src/textdump/write.rs | 2 +- crates/kernel/src/textdump/write_db.rs | 2 +- crates/kernel/src/vm/moo_execute.rs | 20 +-- crates/kernel/src/vm/vm_call.rs | 2 +- crates/values/src/model/defset.rs | 2 +- crates/values/src/var/list.rs | 34 ++--- crates/values/src/var/map.rs | 43 ++---- crates/values/src/var/mod.rs | 9 +- crates/values/src/var/scalar.rs | 30 ++-- crates/values/src/var/storage.rs | 18 +-- crates/values/src/var/string.rs | 2 +- crates/values/src/var/var.rs | 141 +++++++++++------- crates/values/src/var/variant.rs | 19 +-- crates/web-host/src/host/mod.rs | 6 +- 28 files changed, 300 insertions(+), 305 deletions(-) diff --git a/crates/compiler/src/codegen.rs b/crates/compiler/src/codegen.rs index 7f22129a..604894e6 100644 --- a/crates/compiler/src/codegen.rs +++ b/crates/compiler/src/codegen.rs @@ -76,7 +76,7 @@ impl CodegenState { // Create an anonymous jump label at the current position and return its unique ID. fn make_jump_label(&mut self, name: Option) -> Label { let id = Label(self.jumps.len() as u16); - let position = (self.ops.len()).into(); + let position = self.ops.len().into(); self.jumps.push(JumpLabel { id, name, position }); id } @@ -316,15 +316,15 @@ impl CodegenState { self.emit(Op::ImmNone); } Variant::Obj(oid) => { - self.emit(Op::ImmObjid(*oid)); + self.emit(Op::ImmObjid(oid)); } - Variant::Int(i) => match i32::try_from(*i) { + Variant::Int(i) => match i32::try_from(i) { Ok(n) => self.emit(Op::ImmInt(n)), - Err(_) => self.emit(Op::ImmBigInt(*i)), + Err(_) => self.emit(Op::ImmBigInt(i)), }, - Variant::Float(f) => self.emit(Op::ImmFloat(*f)), + Variant::Float(f) => self.emit(Op::ImmFloat(f)), Variant::Err(e) => { - self.emit(Op::ImmErr(*e)); + self.emit(Op::ImmErr(e)); } _ => { let literal = self.add_literal(v); @@ -444,7 +444,7 @@ impl CodegenState { self.pop_stack(1); self.generate_expr(consequence.as_ref())?; let end_label = self.make_jump_label(None); - self.emit(Op::Jump { label: end_label }); + self.emit(Jump { label: end_label }); self.pop_stack(1); self.commit_jump_label(else_label); self.generate_expr(alternative.as_ref())?; @@ -533,7 +533,7 @@ impl CodegenState { self.emit(Op::EndScope { num_bindings: arm.environment_width as u16, }); - self.emit(Op::Jump { label: end_label }); + self.emit(Jump { label: end_label }); // This is where we jump to if the condition is false; either the end of the // if statement, or the start of the next ('else or elseif') arm. @@ -587,7 +587,7 @@ impl CodegenState { for stmt in body { self.generate_stmt(stmt)?; } - self.emit(Op::Jump { label: loop_top }); + self.emit(Jump { label: loop_top }); // This opcode should never get hit. self.emit(Op::EndScope { num_bindings: *environment_width as u16, @@ -666,7 +666,7 @@ impl CodegenState { for s in body { self.generate_stmt(s)?; } - self.emit(Op::Jump { + self.emit(Jump { label: loop_start_label, }); self.emit(Op::EndScope { @@ -730,7 +730,7 @@ impl CodegenState { self.generate_stmt(stmt)?; } if i + 1 < excepts.len() { - self.emit(Op::Jump { label: end_label }); + self.emit(Jump { label: end_label }); } } self.emit(Op::EndScope { diff --git a/crates/console-host/src/main.rs b/crates/console-host/src/main.rs index 7bcfefe2..2127544b 100644 --- a/crates/console-host/src/main.rs +++ b/crates/console-host/src/main.rs @@ -289,7 +289,7 @@ fn console_loop( return; } Ok(ConnectionEvent::RequestInput(requested_input_id)) => { - (*output_input_request_id.lock().unwrap()) = + *output_input_request_id.lock().unwrap() = Some(Uuid::from_u128(requested_input_id)); } } diff --git a/crates/daemon/src/rpc_server.rs b/crates/daemon/src/rpc_server.rs index 1d3382f3..766261c2 100644 --- a/crates/daemon/src/rpc_server.rs +++ b/crates/daemon/src/rpc_server.rs @@ -650,7 +650,7 @@ impl RpcServer { // with its new player objid and login result. // If it's not an objid, that's considered an auth failure. match v.variant() { - Variant::Obj(o) => *o, + Variant::Obj(o) => o, _ => { return Ok(LoginResult(None)); } diff --git a/crates/db-wiredtiger/src/bindings/connection.rs b/crates/db-wiredtiger/src/bindings/connection.rs index cd46e037..3fe2fe8c 100644 --- a/crates/db-wiredtiger/src/bindings/connection.rs +++ b/crates/db-wiredtiger/src/bindings/connection.rs @@ -60,7 +60,7 @@ impl Connection { } /// Open a session. - pub fn open_session(self: Arc, config: SessionConfig) -> Result { + pub fn open_session(self: Arc, config: SessionConfig) -> Result { let mut session: *mut bindings::wiredtiger::WT_SESSION = null::() as _; let config_str = config.as_config_string(); diff --git a/crates/db/src/db_worldstate.rs b/crates/db/src/db_worldstate.rs index 256400d9..e0f4a9f9 100644 --- a/crates/db/src/db_worldstate.rs +++ b/crates/db/src/db_worldstate.rs @@ -363,7 +363,7 @@ impl WorldState for DbTxWorldState { let Variant::Obj(owner) = value.variant() else { return Err(WorldStateError::PropertyTypeMismatch); }; - self.tx.set_object_owner(obj, *owner)?; + self.tx.set_object_owner(obj, owner)?; return Ok(()); } @@ -371,7 +371,7 @@ impl WorldState for DbTxWorldState { let Variant::Int(v) = value.variant() else { return Err(WorldStateError::PropertyTypeMismatch); }; - if *v == 1 { + if v == 1 { flags.set(ObjFlag::Read); } else { flags.clear(ObjFlag::Read); @@ -384,7 +384,7 @@ impl WorldState for DbTxWorldState { let Variant::Int(v) = value.variant() else { return Err(WorldStateError::PropertyTypeMismatch); }; - if *v == 1 { + if v == 1 { flags.set(ObjFlag::Write); } else { flags.clear(ObjFlag::Write); @@ -397,7 +397,7 @@ impl WorldState for DbTxWorldState { let Variant::Int(v) = value.variant() else { return Err(WorldStateError::PropertyTypeMismatch); }; - if *v == 1 { + if v == 1 { flags.set(ObjFlag::Fertile); } else { flags.clear(ObjFlag::Fertile); diff --git a/crates/kernel/src/builtins/bf_list_sets.rs b/crates/kernel/src/builtins/bf_list_sets.rs index 33a0901b..ea045385 100644 --- a/crates/kernel/src/builtins/bf_list_sets.rs +++ b/crates/kernel/src/builtins/bf_list_sets.rs @@ -264,7 +264,7 @@ fn do_re_match(bf_args: &mut BfCallState<'_>, reverse: bool) -> Result) -> Result { let (Variant::Int(start), Variant::Int(end)) = (start.variant(), end.variant()) else { return Err(BfErr::Code(E_INVARG)); }; - mysubs.push((*start as isize, *end as isize)); + mysubs.push((start as isize, end as isize)); } match substitute(&template.as_string(), &mysubs, &source.as_string()) { diff --git a/crates/kernel/src/builtins/bf_num.rs b/crates/kernel/src/builtins/bf_num.rs index 5f3ddb78..150d95fa 100644 --- a/crates/kernel/src/builtins/bf_num.rs +++ b/crates/kernel/src/builtins/bf_num.rs @@ -42,7 +42,7 @@ fn bf_min(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_ARGS)); } - match (bf_args.args[0].variant(), bf_args.args[1].variant()) { + match (&bf_args.args[0].variant(), &bf_args.args[1].variant()) { (Variant::Int(a), Variant::Int(b)) => Ok(Ret(v_int(*a.min(b)))), (Variant::Float(a), Variant::Float(b)) => { let m = R64::from(*a).min(R64::from(*b)); @@ -58,7 +58,7 @@ fn bf_max(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_ARGS)); } - match (bf_args.args[0].variant(), bf_args.args[1].variant()) { + match (&bf_args.args[0].variant(), &bf_args.args[1].variant()) { (Variant::Int(a), Variant::Int(b)) => Ok(Ret(v_int(*a.max(b)))), (Variant::Float(a), Variant::Float(b)) => { let m = R64::from(*a).max(R64::from(*b)); @@ -75,7 +75,7 @@ fn bf_random(bf_args: &mut BfCallState<'_>) -> Result { } let mut rng = rand::thread_rng(); - match bf_args.args.first().map(|var| var.variant()) { + match &bf_args.args.first().map(|var| var.variant()) { Some(Variant::Int(i)) if *i > 0 => Ok(Ret(v_int(rng.gen_range(1..=*i)))), Some(Variant::Int(_)) => Err(BfErr::Code(E_INVARG)), None => Ok(Ret(v_int(rng.gen_range(1..=2147483647)))), @@ -94,12 +94,12 @@ fn bf_floatstr(bf_args: &mut BfCallState<'_>) -> Result { _ => return Err(BfErr::Code(E_TYPE)), }; - let precision = match bf_args.args[1].variant() { + let precision = match &bf_args.args[1].variant() { Variant::Int(i) if *i > 0 => *i as usize, _ => return Err(BfErr::Code(E_TYPE)), }; - let scientific = match bf_args.args[2].variant() { + let scientific = match &bf_args.args[2].variant() { Variant::Int(b) => *b == 1, _ => return Err(BfErr::Code(E_TYPE)), }; @@ -165,7 +165,7 @@ fn bf_sqrt(bf_args: &mut BfCallState<'_>) -> Result { _ => return Err(BfErr::Code(E_TYPE)), }; - if *x < 0.0 { + if x < 0.0 { return Err(BfErr::Code(E_ARGS)); } @@ -183,7 +183,7 @@ fn bf_asin(bf_args: &mut BfCallState<'_>) -> Result { _ => return Err(BfErr::Code(E_TYPE)), }; - if !(-1.0..=1.0).contains(x) { + if !(-1.0..=1.0).contains(&x) { return Err(BfErr::Code(E_ARGS)); } @@ -201,7 +201,7 @@ fn bf_acos(bf_args: &mut BfCallState<'_>) -> Result { _ => return Err(BfErr::Code(E_TYPE)), }; - if !(-1.0..=1.0).contains(x) { + if !(-1.0..=1.0).contains(&x) { return Err(BfErr::Code(E_ARGS)); } @@ -220,7 +220,7 @@ fn bf_atan(bf_args: &mut BfCallState<'_>) -> Result { }; let x = match bf_args.args[1].variant() { - Variant::Float(f) => *f, + Variant::Float(f) => f, _ => return Err(BfErr::Code(E_TYPE)), }; @@ -294,7 +294,7 @@ fn bf_log(bf_args: &mut BfCallState<'_>) -> Result { _ => return Err(BfErr::Code(E_TYPE)), }; - if *x <= 0.0 { + if x <= 0.0 { return Err(BfErr::Code(E_ARGS)); } @@ -312,7 +312,7 @@ fn bf_log10(bf_args: &mut BfCallState<'_>) -> Result { _ => return Err(BfErr::Code(E_TYPE)), }; - if *x <= 0.0 { + if x <= 0.0 { return Err(BfErr::Code(E_ARGS)); } diff --git a/crates/kernel/src/builtins/bf_objects.rs b/crates/kernel/src/builtins/bf_objects.rs index e7d3eb6f..d8b2055d 100644 --- a/crates/kernel/src/builtins/bf_objects.rs +++ b/crates/kernel/src/builtins/bf_objects.rs @@ -21,10 +21,10 @@ use moor_values::model::WorldStateError; use moor_values::model::{ObjFlag, ValSet}; use moor_values::util::BitEnum; use moor_values::Error::{E_ARGS, E_INVARG, E_NACC, E_PERM, E_TYPE}; +use moor_values::Variant; use moor_values::{v_bool, v_int, v_none, v_objid, v_str}; use moor_values::{v_list, Sequence, Symbol}; use moor_values::{v_list_iter, NOTHING}; -use moor_values::Variant; use crate::bf_declare; use crate::builtins::BfRet::{Ret, VmInstr}; @@ -51,10 +51,7 @@ fn bf_valid(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Obj(obj) = bf_args.args[0].variant() else { return Err(BfErr::Code(E_TYPE)); }; - let is_valid = bf_args - .world_state - .valid(*obj) - .map_err(world_state_bf_err)?; + let is_valid = bf_args.world_state.valid(obj).map_err(world_state_bf_err)?; Ok(Ret(v_bool(is_valid))) } bf_declare!(valid, bf_valid); @@ -71,7 +68,7 @@ fn bf_parent(bf_args: &mut BfCallState<'_>) -> Result { } let parent = bf_args .world_state - .parent_of(bf_args.task_perms_who(), *obj) + .parent_of(bf_args.task_perms_who(), obj) .map_err(world_state_bf_err)?; Ok(Ret(v_objid(parent))) } @@ -89,7 +86,7 @@ fn bf_chparent(bf_args: &mut BfCallState<'_>) -> Result { }; bf_args .world_state - .change_parent(bf_args.task_perms_who(), *obj, *new_parent) + .change_parent(bf_args.task_perms_who(), obj, new_parent) .map_err(world_state_bf_err)?; Ok(Ret(v_none())) } @@ -104,7 +101,7 @@ fn bf_children(bf_args: &mut BfCallState<'_>) -> Result { }; let children = bf_args .world_state - .children_of(bf_args.task_perms_who(), *obj) + .children_of(bf_args.task_perms_who(), obj) .map_err(world_state_bf_err)?; let children = children.iter().map(v_objid).collect::>(); @@ -326,7 +323,7 @@ fn bf_recycle(bf_args: &mut BfCallState<'_>) -> Result { // look again anyways. let Ok(exitfunc) = bf_args.world_state.find_method_verb_on( bf_args.task_perms_who(), - *head_obj, + head_obj, *EXITFUNC_SYM, ) else { // If there's no :exitfunc, we can just move on to the next object. @@ -344,8 +341,8 @@ fn bf_recycle(bf_args: &mut BfCallState<'_>) -> Result { resolved_verb: exitfunc, call: VerbCall { verb_name: *EXITFUNC_SYM, - location: *head_obj, - this: *head_obj, + location: head_obj, + this: head_obj, player: bf_args.exec_state.top().player, args: vec![v_objid(obj)], argstr: "".to_string(), @@ -613,7 +610,7 @@ fn bf_verbs(bf_args: &mut BfCallState<'_>) -> Result { }; let verbs = bf_args .world_state - .verbs(bf_args.task_perms_who(), *obj) + .verbs(bf_args.task_perms_who(), obj) .map_err(world_state_bf_err)?; let verbs: Vec<_> = verbs .iter() @@ -636,7 +633,7 @@ fn bf_properties(bf_args: &mut BfCallState<'_>) -> Result { }; let props = bf_args .world_state - .properties(bf_args.task_perms_who(), *obj) + .properties(bf_args.task_perms_who(), obj) .map_err(world_state_bf_err)?; let props: Vec<_> = props.iter().map(|p| v_str(p.name())).collect(); Ok(Ret(v_list(&props))) @@ -654,7 +651,7 @@ fn bf_set_player_flag(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_INVARG)); }; - let f = *f == 1; + let f = f == 1; // User must be a wizard. bf_args @@ -666,7 +663,7 @@ fn bf_set_player_flag(bf_args: &mut BfCallState<'_>) -> Result { // Get and set object flags let mut flags = bf_args .world_state - .flags_of(*obj) + .flags_of(obj) .map_err(world_state_bf_err)?; if f { @@ -677,12 +674,12 @@ fn bf_set_player_flag(bf_args: &mut BfCallState<'_>) -> Result { bf_args .world_state - .set_flags_of(bf_args.task_perms_who(), *obj, flags) + .set_flags_of(bf_args.task_perms_who(), obj, flags) .map_err(world_state_bf_err)?; // If the object was player, update the VM's copy of the perms. - if *obj == bf_args.task_perms().map_err(world_state_bf_err)?.who { - bf_args.exec_state.set_task_perms(*obj); + if obj == bf_args.task_perms().map_err(world_state_bf_err)?.who { + bf_args.exec_state.set_task_perms(obj); } Ok(Ret(v_none())) diff --git a/crates/kernel/src/builtins/bf_properties.rs b/crates/kernel/src/builtins/bf_properties.rs index cad2c3c2..ae72f8da 100644 --- a/crates/kernel/src/builtins/bf_properties.rs +++ b/crates/kernel/src/builtins/bf_properties.rs @@ -42,7 +42,7 @@ fn bf_property_info(bf_args: &mut BfCallState<'_>) -> Result { .world_state .get_property_info( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(&prop_name.as_string()), ) .map_err(world_state_bf_err)?; @@ -107,7 +107,7 @@ fn info_to_prop_attrs(info: &List) -> InfoParseResult { name, value: None, location: None, - owner: Some(*owner), + owner: Some(owner), flags: Some(flags), }) } @@ -126,7 +126,7 @@ fn bf_set_property_info(bf_args: &mut BfCallState<'_>) -> Result { return Err(Code(E_TYPE)); }; - let attrs = match info_to_prop_attrs(info) { + let attrs = match info_to_prop_attrs(&info) { InfoParseResult::Fail(e) => { return Err(Code(e)); } @@ -137,7 +137,7 @@ fn bf_set_property_info(bf_args: &mut BfCallState<'_>) -> Result { .world_state .set_property_info( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(prop_name.as_string().as_str()), attrs, ) @@ -160,7 +160,7 @@ fn bf_is_clear_property(bf_args: &mut BfCallState<'_>) -> Result { .world_state .is_property_clear( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(prop_name.as_string().as_str()), ) .map_err(world_state_bf_err)?; @@ -182,7 +182,7 @@ fn bf_clear_property(bf_args: &mut BfCallState<'_>) -> Result { .world_state .clear_property( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(prop_name.as_string().as_str()), ) .map_err(world_state_bf_err)?; @@ -205,7 +205,7 @@ fn bf_add_property(bf_args: &mut BfCallState<'_>) -> Result { return Err(Code(E_ARGS)); }; - let attrs = match info_to_prop_attrs(info) { + let attrs = match info_to_prop_attrs(&info) { InfoParseResult::Fail(e) => { return Err(Code(e)); } @@ -216,8 +216,8 @@ fn bf_add_property(bf_args: &mut BfCallState<'_>) -> Result { .world_state .define_property( bf_args.task_perms_who(), - *location, - *location, + location, + location, Symbol::mk_case_insensitive(name.as_string().as_str()), attrs.owner.unwrap(), attrs.flags.unwrap(), @@ -242,7 +242,7 @@ fn bf_delete_property(bf_args: &mut BfCallState<'_>) -> Result { .world_state .delete_property( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(prop_name.as_string().as_str()), ) .map_err(world_state_bf_err)?; diff --git a/crates/kernel/src/builtins/bf_server.rs b/crates/kernel/src/builtins/bf_server.rs index ee723860..b3d621d4 100644 --- a/crates/kernel/src/builtins/bf_server.rs +++ b/crates/kernel/src/builtins/bf_server.rs @@ -75,7 +75,7 @@ fn bf_notify(bf_args: &mut BfCallState<'_>) -> Result { bf_args .task_perms() .map_err(world_state_bf_err)? - .check_obj_owner_perms(*player) + .check_obj_owner_perms(player) .map_err(world_state_bf_err)?; let content_type = if bf_args.config.rich_notify && bf_args.args.len() == 3 { @@ -93,7 +93,7 @@ fn bf_notify(bf_args: &mut BfCallState<'_>) -> Result { bf_args.args[1].clone(), content_type, ); - bf_args.task_scheduler_client.notify(*player, event); + bf_args.task_scheduler_client.notify(player, event); // MOO docs say this should return none, but in reality it returns 1? Ok(Ret(v_int(1))) @@ -125,7 +125,7 @@ fn bf_is_player(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_TYPE)); }; - let is_player = match bf_args.world_state.flags_of(*player) { + let is_player = match bf_args.world_state.flags_of(player) { Ok(flags) => flags.contains(ObjFlag::User), Err(WorldStateError::ObjectNotFound(_)) => return Err(BfErr::Code(E_ARGS)), Err(e) => return Err(world_state_bf_err(e)), @@ -205,7 +205,7 @@ fn bf_idle_seconds(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Obj(who) = bf_args.args[0].variant() else { return Err(BfErr::Code(E_TYPE)); }; - let Ok(idle_seconds) = bf_args.session.idle_seconds(*who) else { + let Ok(idle_seconds) = bf_args.session.idle_seconds(who) else { return Err(BfErr::Code(E_ARGS)); }; @@ -220,7 +220,7 @@ fn bf_connected_seconds(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Obj(who) = bf_args.args[0].variant() else { return Err(BfErr::Code(E_TYPE)); }; - let Ok(connected_seconds) = bf_args.session.connected_seconds(*who) else { + let Ok(connected_seconds) = bf_args.session.connected_seconds(who) else { return Err(BfErr::Code(E_INVARG)); }; @@ -250,12 +250,12 @@ fn bf_connection_name(bf_args: &mut BfCallState<'_>) -> Result { .map_err(world_state_bf_err)? .check_is_wizard() .map_err(world_state_bf_err)? - && caller != *player + && caller != player { return Err(BfErr::Code(E_PERM)); } - let Ok(connection_name) = bf_args.session.connection_name(*player) else { + let Ok(connection_name) = bf_args.session.connection_name(player) else { return Err(BfErr::Code(E_ARGS)); }; @@ -311,7 +311,7 @@ fn bf_ctime(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Int(time) = bf_args.args[0].variant() else { return Err(BfErr::Code(E_TYPE)); }; - if *time < 0 { + if time < 0 { SystemTime::UNIX_EPOCH - Duration::from_secs(time.unsigned_abs()) } else { SystemTime::UNIX_EPOCH + Duration::from_secs(time.unsigned_abs()) @@ -361,7 +361,7 @@ fn bf_raise(bf_args: &mut BfCallState<'_>) -> Result { None }; - Err(BfErr::Raise(*err, msg, value)) + Err(BfErr::Raise(err, msg, value)) } bf_declare!(raise, bf_raise); @@ -391,8 +391,8 @@ fn bf_suspend(bf_args: &mut BfCallState<'_>) -> Result { None } else { let seconds = match bf_args.args[0].variant() { - Variant::Float(seconds) => *seconds, - Variant::Int(seconds) => *seconds as f64, + Variant::Float(seconds) => seconds, + Variant::Int(seconds) => seconds as f64, _ => return Err(BfErr::Code(E_TYPE)), }; if seconds < 0.0 { @@ -418,7 +418,7 @@ fn bf_read(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_ARGS)); }; let player = bf_args.exec_state.top().player; - if *requested_player != player { + if requested_player != player { // We log this because we'd like to know if cores are trying to do this. warn!( requested_player = ?requested_player, @@ -485,7 +485,7 @@ fn bf_kill_task(bf_args: &mut BfCallState<'_>) -> Result { // If the task ID is itself, that means returning an Complete execution result, which will cascade // back to the task loop and it will terminate itself. // Not sure this is *exactly* what MOO does, but it's close enough for now. - let victim_task_id = *victim_task_id as TaskId; + let victim_task_id = victim_task_id as TaskId; if victim_task_id == bf_args.exec_state.task_id { return Ok(VmInstr(ExecutionResult::Complete(v_none()))); @@ -496,7 +496,7 @@ fn bf_kill_task(bf_args: &mut BfCallState<'_>) -> Result { bf_args.task_perms().map_err(world_state_bf_err)?, ); if let Variant::Err(err) = result.variant() { - return Err(BfErr::Code(*err)); + return Err(BfErr::Code(err)); } Ok(Ret(result)) } @@ -518,7 +518,7 @@ fn bf_resume(bf_args: &mut BfCallState<'_>) -> Result { v_none() }; - let task_id = *resume_task_id as TaskId; + let task_id = resume_task_id as TaskId; // Resuming ourselves makes no sense, it's not suspended. E_INVARG. if task_id == bf_args.exec_state.task_id { @@ -531,7 +531,7 @@ fn bf_resume(bf_args: &mut BfCallState<'_>) -> Result { return_value.clone(), ); if let Variant::Err(err) = result.variant() { - return Err(BfErr::Code(*err)); + return Err(BfErr::Code(err)); } Ok(Ret(result)) } @@ -584,11 +584,11 @@ fn bf_boot_player(bf_args: &mut BfCallState<'_>) -> Result { }; let task_perms = bf_args.task_perms().map_err(world_state_bf_err)?; - if task_perms.who != *player && !task_perms.check_is_wizard().map_err(world_state_bf_err)? { + if task_perms.who != player && !task_perms.check_is_wizard().map_err(world_state_bf_err)? { return Err(BfErr::Code(E_PERM)); } - bf_args.task_scheduler_client.boot_player(*player); + bf_args.task_scheduler_client.boot_player(player); Ok(Ret(v_none())) } @@ -642,7 +642,7 @@ fn bf_server_log(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Int(is_error) = bf_args.args[1].variant() else { return Err(BfErr::Code(E_TYPE)); }; - *is_error == 1 + is_error == 1 } else { false }; @@ -689,10 +689,12 @@ fn bf_function_info_to_list(bf: &Builtin) -> Var { ArgType::AnyNum => v_int(-2), }); - v_list(&[v_str(bf.name.as_str()), + v_list(&[ + v_str(bf.name.as_str()), min_args, max_args, - v_list_iter(types)]) + v_list_iter(types), + ]) } fn bf_function_info(bf_args: &mut BfCallState<'_>) -> Result { diff --git a/crates/kernel/src/builtins/bf_strings.rs b/crates/kernel/src/builtins/bf_strings.rs index 865adef4..fe88fc60 100644 --- a/crates/kernel/src/builtins/bf_strings.rs +++ b/crates/kernel/src/builtins/bf_strings.rs @@ -57,7 +57,7 @@ fn bf_strsub(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Int(case_matters) = bf_args.args[3].variant() else { return Err(BfErr::Code(E_TYPE)); }; - *case_matters == 1 + case_matters == 1 } else { return Err(BfErr::Code(E_ARGS)); }; @@ -112,7 +112,7 @@ fn bf_index(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Int(case_matters) = bf_args.args[2].variant() else { return Err(BfErr::Code(E_TYPE)); }; - *case_matters == 1 + case_matters == 1 } else { return Err(BfErr::Code(E_ARGS)); }; @@ -136,7 +136,7 @@ fn bf_rindex(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Int(case_matters) = bf_args.args[2].variant() else { return Err(BfErr::Code(E_TYPE)); }; - *case_matters == 1 + case_matters == 1 } else { return Err(BfErr::Code(E_ARGS)); }; diff --git a/crates/kernel/src/builtins/bf_values.rs b/crates/kernel/src/builtins/bf_values.rs index 1e68acde..90cdb374 100644 --- a/crates/kernel/src/builtins/bf_values.rs +++ b/crates/kernel/src/builtins/bf_values.rs @@ -62,8 +62,8 @@ fn bf_toint(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_ARGS)); } match bf_args.args[0].variant() { - Variant::Int(i) => Ok(Ret(v_int(*i))), - Variant::Float(f) => Ok(Ret(v_int(*f as i64))), + Variant::Int(i) => Ok(Ret(v_int(i))), + Variant::Float(f) => Ok(Ret(v_int(f as i64))), Variant::Obj(o) => Ok(Ret(v_int(o.0))), Variant::Str(s) => { let i = s.as_string().as_str().parse::(); @@ -72,7 +72,7 @@ fn bf_toint(bf_args: &mut BfCallState<'_>) -> Result { Err(_) => Ok(Ret(v_int(0))), } } - Variant::Err(e) => Ok(Ret(v_int(*e as i64))), + Variant::Err(e) => Ok(Ret(v_int(e as i64))), _ => Err(BfErr::Code(E_INVARG)), } } @@ -83,8 +83,8 @@ fn bf_toobj(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_ARGS)); } match bf_args.args[0].variant() { - Variant::Int(i) => Ok(Ret(v_obj(*i))), - Variant::Float(f) => Ok(Ret(v_obj(*f as i64))), + Variant::Int(i) => Ok(Ret(v_obj(i))), + Variant::Float(f) => Ok(Ret(v_obj(f as i64))), Variant::Str(s) if s.as_string().as_str().starts_with('#') => { let i = s.as_string().as_str()[1..].parse::(); match i { @@ -109,8 +109,8 @@ fn bf_tofloat(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_ARGS)); } match bf_args.args[0].variant() { - Variant::Int(i) => Ok(Ret(v_float(*i as f64))), - Variant::Float(f) => Ok(Ret(v_float(*f))), + Variant::Int(i) => Ok(Ret(v_float(i as f64))), + Variant::Float(f) => Ok(Ret(v_float(f))), Variant::Str(s) => { let f = s.as_string().as_str().parse::(); match f { @@ -118,7 +118,7 @@ fn bf_tofloat(bf_args: &mut BfCallState<'_>) -> Result { Err(_) => Ok(Ret(v_float(0.0))), } } - Variant::Err(e) => Ok(Ret(v_float(*e as u8 as f64))), + Variant::Err(e) => Ok(Ret(v_float(e as u8 as f64))), _ => Err(BfErr::Code(E_INVARG)), } } @@ -176,12 +176,12 @@ fn bf_object_bytes(bf_args: &mut BfCallState<'_>) -> Result { let Variant::Obj(o) = bf_args.args[0].variant() else { return Err(BfErr::Code(E_INVARG)); }; - if !bf_args.world_state.valid(*o).map_err(world_state_bf_err)? { + if !bf_args.world_state.valid(o).map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); }; let size = bf_args .world_state - .object_bytes(bf_args.caller_perms(), *o) + .object_bytes(bf_args.caller_perms(), o) .map_err(world_state_bf_err)?; Ok(Ret(v_int(size as i64))) } diff --git a/crates/kernel/src/builtins/bf_verbs.rs b/crates/kernel/src/builtins/bf_verbs.rs index d1d90636..44f3fd02 100644 --- a/crates/kernel/src/builtins/bf_verbs.rs +++ b/crates/kernel/src/builtins/bf_verbs.rs @@ -53,7 +53,7 @@ fn bf_verb_info(bf_args: &mut BfCallState<'_>) -> Result { if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); @@ -64,19 +64,18 @@ fn bf_verb_info(bf_args: &mut BfCallState<'_>) -> Result { .world_state .get_verb( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(&verb_desc.as_string()), ) .map_err(world_state_bf_err)?, Variant::Int(verb_index) => { - let verb_index = *verb_index; if verb_index < 1 { return Err(BfErr::Code(E_INVARG)); } let verb_index = (verb_index as usize) - 1; bf_args .world_state - .get_verb_at_index(bf_args.task_perms_who(), *obj, verb_index) + .get_verb_at_index(bf_args.task_perms_who(), obj, verb_index) .map_err(world_state_bf_err)? } _ => { @@ -118,7 +117,6 @@ fn get_verbdef(obj: Objid, verbspec: Var, bf_args: &BfCallState<'_>) -> Result { - let verb_index = *verb_index; if verb_index < 1 { return Err(BfErr::Code(E_INVARG)); } @@ -144,9 +142,9 @@ fn parse_verb_info(info: &List) -> Result { return Err(E_INVARG); } match ( - info.index(0).unwrap().variant(), - info.index(1).unwrap().variant(), - info.index(2).unwrap().variant(), + info.index(0)?.variant(), + info.index(1)?.variant(), + info.index(2)?.variant(), ) { (Variant::Obj(owner), Variant::Str(perms_str), Variant::Str(names)) => { let mut perms = BitEnum::new(); @@ -169,7 +167,7 @@ fn parse_verb_info(info: &List) -> Result { Ok(VerbAttrs { definer: None, - owner: Some(*owner), + owner: Some(owner), names: Some(name_strings), flags: Some(perms), args_spec: None, @@ -195,11 +193,11 @@ fn bf_set_verb_info(bf_args: &mut BfCallState<'_>) -> Result { if info.len() != 3 { return Err(BfErr::Code(E_ARGS)); } - let update_attrs = parse_verb_info(info).map_err(BfErr::Code)?; + let update_attrs = parse_verb_info(&info).map_err(BfErr::Code)?; if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); @@ -211,21 +209,20 @@ fn bf_set_verb_info(bf_args: &mut BfCallState<'_>) -> Result { .world_state .update_verb( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(&verb_name.as_string()), update_attrs, ) .map_err(world_state_bf_err)?; } Variant::Int(verb_index) => { - let verb_index = *verb_index; if verb_index < 1 { return Err(BfErr::Code(E_INVARG)); } let verb_index = (verb_index as usize) - 1; bf_args .world_state - .update_verb_at_index(bf_args.task_perms_who(), *obj, verb_index, update_attrs) + .update_verb_at_index(bf_args.task_perms_who(), obj, verb_index, update_attrs) .map_err(world_state_bf_err)?; } _ => return Err(BfErr::Code(E_TYPE)), @@ -244,13 +241,13 @@ fn bf_verb_args(bf_args: &mut BfCallState<'_>) -> Result { }; if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); } - let verbdef = match get_verbdef(*obj, bf_args.args[1].clone(), bf_args) { + let verbdef = match get_verbdef(obj, bf_args.args[1].clone(), bf_args) { Ok(v) => v, Err(e) => return Err(e), }; @@ -271,9 +268,9 @@ fn parse_verb_args(verbinfo: &List) -> Result { return Err(E_ARGS); } match ( - verbinfo.index(0).unwrap().variant(), - verbinfo.index(1).unwrap().variant(), - verbinfo.index(2).unwrap().variant(), + verbinfo.index(0)?.variant(), + verbinfo.index(1)?.variant(), + verbinfo.index(2)?.variant(), ) { (Variant::Str(dobj_str), Variant::Str(prep_str), Variant::Str(iobj_str)) => { let (Some(dobj), Some(prep), Some(iobj)) = ( @@ -305,13 +302,13 @@ fn bf_set_verb_args(bf_args: &mut BfCallState<'_>) -> Result { } if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); } - let args = parse_verb_args(verbinfo).map_err(BfErr::Code)?; + let args = parse_verb_args(&verbinfo).map_err(BfErr::Code)?; let update_attrs = VerbAttrs { definer: None, @@ -328,21 +325,20 @@ fn bf_set_verb_args(bf_args: &mut BfCallState<'_>) -> Result { .world_state .update_verb( bf_args.task_perms_who(), - *obj, + obj, Symbol::mk_case_insensitive(&verb_name.as_string()), update_attrs, ) .map_err(world_state_bf_err)?; } Variant::Int(verb_index) => { - let verb_index = *verb_index; if verb_index < 1 { return Err(BfErr::Code(E_ARGS)); } let verb_index = (verb_index as usize) - 1; bf_args .world_state - .update_verb_at_index(bf_args.task_perms_who(), *obj, verb_index, update_attrs) + .update_verb_at_index(bf_args.task_perms_who(), obj, verb_index, update_attrs) .map_err(world_state_bf_err)?; } _ => return Err(BfErr::Code(E_TYPE)), @@ -361,7 +357,7 @@ fn bf_verb_code(bf_args: &mut BfCallState<'_>) -> Result { }; if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); @@ -376,7 +372,7 @@ fn bf_verb_code(bf_args: &mut BfCallState<'_>) -> Result { { return Err(BfErr::Code(E_PERM)); } - let verbdef = match get_verbdef(*obj, bf_args.args[1].clone(), bf_args) { + let verbdef = match get_verbdef(obj, bf_args.args[1].clone(), bf_args) { Ok(v) => v, Err(e) => return Err(e), }; @@ -394,7 +390,7 @@ fn bf_verb_code(bf_args: &mut BfCallState<'_>) -> Result { // Retrieve the binary for the verb. let verb_info = bf_args .world_state - .retrieve_verb(bf_args.task_perms_who(), *obj, verbdef.uuid()) + .retrieve_verb(bf_args.task_perms_who(), obj, verbdef.uuid()) .map_err(world_state_bf_err)?; // If the binary is empty, just return empty rather than try to decode it. @@ -440,7 +436,7 @@ fn bf_set_verb_code(bf_args: &mut BfCallState<'_>) -> Result { }; if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); @@ -456,7 +452,7 @@ fn bf_set_verb_code(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_PERM)); } - let verbdef = match get_verbdef(*obj, bf_args.args[1].clone(), bf_args) { + let verbdef = match get_verbdef(obj, bf_args.args[1].clone(), bf_args) { Ok(v) => v, Err(e) => return Err(e), }; @@ -505,7 +501,7 @@ fn bf_set_verb_code(bf_args: &mut BfCallState<'_>) -> Result { }; bf_args .world_state - .update_verb_with_id(bf_args.task_perms_who(), *obj, verbdef.uuid(), update_attrs) + .update_verb_with_id(bf_args.task_perms_who(), obj, verbdef.uuid(), update_attrs) .map_err(world_state_bf_err)?; Ok(Ret(v_none())) } @@ -527,7 +523,7 @@ fn bf_add_verb(bf_args: &mut BfCallState<'_>) -> Result { }; if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); @@ -542,14 +538,14 @@ fn bf_add_verb(bf_args: &mut BfCallState<'_>) -> Result { { return Err(BfErr::Code(E_PERM)); } - let verbargs = parse_verb_args(args).map_err(BfErr::Code)?; - let verbinfo = parse_verb_info(info).map_err(BfErr::Code)?; + let verbargs = parse_verb_args(&args).map_err(BfErr::Code)?; + let verbinfo = parse_verb_info(&info).map_err(BfErr::Code)?; bf_args .world_state .add_verb( bf_args.task_perms_who(), - *obj, + obj, verbinfo.names.unwrap(), verbinfo.owner.unwrap(), verbinfo.flags.unwrap(), @@ -573,7 +569,7 @@ fn bf_delete_verb(bf_args: &mut BfCallState<'_>) -> Result { }; if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); @@ -589,14 +585,14 @@ fn bf_delete_verb(bf_args: &mut BfCallState<'_>) -> Result { return Err(BfErr::Code(E_PERM)); } - let verbdef = match get_verbdef(*obj, bf_args.args[1].clone(), bf_args) { + let verbdef = match get_verbdef(obj, bf_args.args[1].clone(), bf_args) { Ok(v) => v, Err(e) => return Err(e), }; bf_args .world_state - .remove_verb(bf_args.task_perms_who(), *obj, verbdef.uuid()) + .remove_verb(bf_args.task_perms_who(), obj, verbdef.uuid()) .map_err(world_state_bf_err)?; Ok(Ret(v_none())) @@ -617,13 +613,13 @@ fn bf_disassemble(bf_args: &mut BfCallState<'_>) -> Result { }; if !bf_args .world_state - .valid(*obj) + .valid(obj) .map_err(world_state_bf_err)? { return Err(BfErr::Code(E_INVARG)); } - let verbdef = match get_verbdef(*obj, bf_args.args[1].clone(), bf_args) { + let verbdef = match get_verbdef(obj, bf_args.args[1].clone(), bf_args) { Ok(v) => v, Err(e) => return Err(e), }; @@ -636,7 +632,7 @@ fn bf_disassemble(bf_args: &mut BfCallState<'_>) -> Result { let verb_info = bf_args .world_state - .retrieve_verb(bf_args.task_perms_who(), *obj, verbdef.uuid()) + .retrieve_verb(bf_args.task_perms_who(), obj, verbdef.uuid()) .map_err(world_state_bf_err)?; if verb_info.binary().is_empty() { diff --git a/crates/kernel/src/tasks/scheduler.rs b/crates/kernel/src/tasks/scheduler.rs index 92dc8b59..1c2f2506 100644 --- a/crates/kernel/src/tasks/scheduler.rs +++ b/crates/kernel/src/tasks/scheduler.rs @@ -135,7 +135,7 @@ fn load_int_sysprop(server_options_obj: Objid, name: Symbol, tx: &dyn WorldState return None; }; match value.variant() { - Variant::Int(i) if *i >= 0 => Some(*i as u64), + Variant::Int(i) if i >= 0 => Some(i as u64), _ => { warn!("$bg_seconds is not a positive integer"); None @@ -246,20 +246,20 @@ impl Scheduler { return; }; - if let Some(bg_seconds) = load_int_sysprop(*server_options_obj, *BG_SECONDS, tx.as_ref()) { + if let Some(bg_seconds) = load_int_sysprop(server_options_obj, *BG_SECONDS, tx.as_ref()) { so.bg_seconds = bg_seconds; } - if let Some(bg_ticks) = load_int_sysprop(*server_options_obj, *BG_TICKS, tx.as_ref()) { + if let Some(bg_ticks) = load_int_sysprop(server_options_obj, *BG_TICKS, tx.as_ref()) { so.bg_ticks = bg_ticks as usize; } - if let Some(fg_seconds) = load_int_sysprop(*server_options_obj, *FG_SECONDS, tx.as_ref()) { + if let Some(fg_seconds) = load_int_sysprop(server_options_obj, *FG_SECONDS, tx.as_ref()) { so.fg_seconds = fg_seconds; } - if let Some(fg_ticks) = load_int_sysprop(*server_options_obj, *FG_TICKS, tx.as_ref()) { + if let Some(fg_ticks) = load_int_sysprop(server_options_obj, *FG_TICKS, tx.as_ref()) { so.fg_ticks = fg_ticks as usize; } if let Some(max_stack_depth) = - load_int_sysprop(*server_options_obj, *MAX_STACK_DEPTH, tx.as_ref()) + load_int_sysprop(server_options_obj, *MAX_STACK_DEPTH, tx.as_ref()) { so.max_stack_depth = max_stack_depth as usize; } @@ -566,7 +566,7 @@ impl Scheduler { }; let Ok(property_value) = - world_state.retrieve_property(SYSTEM_OBJECT, *sysprop, property) + world_state.retrieve_property(SYSTEM_OBJECT, sysprop, property) else { reply .send(Err(CommandExecutionError(CommandError::NoObjectMatch))) diff --git a/crates/kernel/src/textdump/write.rs b/crates/kernel/src/textdump/write.rs index acb2a545..f839b32b 100644 --- a/crates/kernel/src/textdump/write.rs +++ b/crates/kernel/src/textdump/write.rs @@ -73,7 +73,7 @@ impl TextdumpWriter { writeln!(self.writer, "{}\n{}", VarType::TYPE_STR as i64, s)?; } Variant::Err(e) => { - writeln!(self.writer, "{}\n{}", VarType::TYPE_ERR as i64, *e as u8)?; + writeln!(self.writer, "{}\n{}", VarType::TYPE_ERR as i64, e as u8)?; } Variant::List(l) => { writeln!(self.writer, "{}\n{}", VarType::TYPE_LIST as i64, l.len())?; diff --git a/crates/kernel/src/textdump/write_db.rs b/crates/kernel/src/textdump/write_db.rs index e304b2f8..2192ed35 100644 --- a/crates/kernel/src/textdump/write_db.rs +++ b/crates/kernel/src/textdump/write_db.rs @@ -178,7 +178,7 @@ pub fn make_textdump(tx: &dyn LoaderInterface, version: Option<&str>) -> Textdum .get_verb_binary(*db_objid, verb.uuid()) .expect("Failed to get verb binary"); - let program = if !(binary.is_empty()) { + let program = if !binary.is_empty() { let program = Program::from_bytes(binary).expect("Failed to parse verb binary"); if !program.main_vector.is_empty() { let ast = moor_compiler::program_to_tree(&program) diff --git a/crates/kernel/src/vm/moo_execute.rs b/crates/kernel/src/vm/moo_execute.rs index 390b3720..41baf9c3 100644 --- a/crates/kernel/src/vm/moo_execute.rs +++ b/crates/kernel/src/vm/moo_execute.rs @@ -169,7 +169,7 @@ pub fn moo_frame_execute( f.jump(end_label); return state.raise_error(E_TYPE); }; - let count = *count as usize; + let count = count as usize; let Variant::List(l) = list.variant() else { f.pop(); f.pop(); @@ -523,7 +523,7 @@ pub fn moo_frame_execute( return state.push_error(E_INVIND); }; let propname = Symbol::mk_case_insensitive(&propname.as_string()); - let result = world_state.retrieve_property(a.permissions, *obj, propname); + let result = world_state.retrieve_property(a.permissions, obj, propname); match result { Ok(v) => { f.poke(0, v); @@ -547,7 +547,7 @@ pub fn moo_frame_execute( return state.push_error(E_INVIND); }; let propname = Symbol::mk_case_insensitive(&propname.as_string()); - let result = world_state.retrieve_property(a.permissions, *obj, propname); + let result = world_state.retrieve_property(a.permissions, obj, propname); match result { Ok(v) => { f.push(v); @@ -573,7 +573,7 @@ pub fn moo_frame_execute( let propname = Symbol::mk_case_insensitive(&propname.as_string()); let update_result = - world_state.update_property(a.permissions, *obj, propname, &rhs.clone()); + world_state.update_property(a.permissions, obj, propname, &rhs.clone()); match update_result { Ok(()) => { @@ -590,8 +590,8 @@ pub fn moo_frame_execute( let time = f.pop(); let time = match time.variant() { - Variant::Int(time) => *time as f64, - Variant::Float(time) => *time, + Variant::Int(time) => time as f64, + Variant::Float(time) => time, _ => { return state.push_error(E_TYPE); } @@ -618,7 +618,7 @@ pub fn moo_frame_execute( let Variant::List(args) = args.variant() else { return state.push_error(E_TYPE); }; - return state.prepare_pass_verb(world_state, args); + return state.prepare_pass_verb(world_state, &args); } Op::CallVerb => { let (args, verb, obj) = (f.pop(), f.pop(), f.pop()); @@ -629,7 +629,7 @@ pub fn moo_frame_execute( } }; let verb = Symbol::mk_case_insensitive(&verb.as_string()); - return state.prepare_call_verb(world_state, *obj, verb, args.clone()); + return state.prepare_call_verb(world_state, obj, verb, args.clone()); } Op::Return => { let ret_val = f.pop(); @@ -667,12 +667,12 @@ pub fn moo_frame_execute( let Variant::Err(e) = v.variant() else { panic!("Error codes list contains non-error code"); }; - *e + e }); f.catch_stack .push((CatchType::Errors(error_codes.collect()), *label)); } - Variant::Int(i) if *i == 0 => { + Variant::Int(0) => { f.catch_stack.push((CatchType::Any, *label)); } _ => { diff --git a/crates/kernel/src/vm/vm_call.rs b/crates/kernel/src/vm/vm_call.rs index 52300062..234e5a56 100644 --- a/crates/kernel/src/vm/vm_call.rs +++ b/crates/kernel/src/vm/vm_call.rs @@ -72,7 +72,7 @@ impl VMExecState { world_state: &mut dyn WorldState, this: Objid, verb_name: Symbol, - args: List, + args: Arc, ) -> ExecutionResult { let call = VerbCall { verb_name, diff --git a/crates/values/src/model/defset.rs b/crates/values/src/model/defset.rs index 639e1c9d..d717d0c5 100644 --- a/crates/values/src/model/defset.rs +++ b/crates/values/src/model/defset.rs @@ -41,7 +41,7 @@ pub struct Defs { } impl Display for Defs { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let names = self .iter() .map(|p| p.names().iter().map(|s| s.to_string()).join(":")) diff --git a/crates/values/src/var/list.rs b/crates/values/src/var/list.rs index 1844a4bb..9ea77b82 100644 --- a/crates/values/src/var/list.rs +++ b/crates/values/src/var/list.rs @@ -20,7 +20,7 @@ use crate::var::Error::E_RANGE; use crate::var::Sequence; use crate::var::{Error, VarType}; use bytes::Bytes; -use flexbuffers::{BuilderOptions, Reader, VectorReader}; +use flexbuffers::{BuilderOptions, VectorReader}; use num_traits::ToPrimitive; use std::cmp::max; use std::hash::Hash; @@ -28,7 +28,7 @@ use std::hash::Hash; #[derive(Clone)] pub struct List { // Reader must be boxed to avoid overfilling the stack. - pub reader: Box>, + pub reader: VectorReader, } impl List { @@ -45,9 +45,8 @@ impl List { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + let buf = VarBuffer(buf); + Var(buf) } pub fn iter(&self) -> impl Iterator + '_ { @@ -70,9 +69,9 @@ impl List { /// Add `item` to the list but only if it's not already there. pub fn set_add(&self, item: &Var) -> Result { - // Is the item already in the list? If so, just clone. + // Is the item already in the list? If so, just clone self if self.iter().any(|v| v == *item) { - return Ok(Var(Variant::List(self.clone()))); + return Ok(Var::from_variant(Variant::List(self.clone().into()))); } let set_added_iter = self.iter().chain(std::iter::once(item.clone())); Ok(v_list_iter(set_added_iter)) @@ -127,10 +126,7 @@ impl Sequence for List { if index >= self.reader.len() { return Err(E_RANGE); } - let result = self.reader.index(index).unwrap(); - let v = Variant::from_reader(result); - let v = Var(v); - Ok(v) + Ok(Var::from_reader(self.reader.index(index).unwrap())) } fn index_set(&self, index: usize, value: &Var) -> Result { @@ -285,9 +281,7 @@ impl FromIterator for Var { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(buf)) } } #[cfg(test)] @@ -313,7 +307,7 @@ mod tests { let r = l.index(&Var::mk_integer(1), IndexMode::ZeroBased).unwrap(); let r = r.variant(); match r { - Variant::Int(i) => assert_eq!(*i, 2), + Variant::Int(i) => assert_eq!(i, 2), _ => panic!("Expected integer, got {:?}", r), } } @@ -362,7 +356,7 @@ mod tests { let r = l.index(&Var::mk_integer(1), IndexMode::ZeroBased).unwrap(); let r = r.variant(); match r { - Variant::Int(i) => assert_eq!(*i, 2), + Variant::Int(i) => assert_eq!(i, 2), _ => panic!("Expected integer, got {:?}", r), } } @@ -383,7 +377,7 @@ mod tests { let r = l.index(1).unwrap(); let r = r.variant(); match r { - Variant::Int(i) => assert_eq!(*i, 42), + Variant::Int(i) => assert_eq!(i, 42), _ => panic!("Expected integer, got {:?}", r), } } @@ -431,13 +425,13 @@ mod tests { let l = Var::mk_list(&[Var::mk_integer(1), Var::mk_integer(2), Var::mk_integer(3)]); // Only works on list variants. let l = match l.variant() { - Variant::List(l) => l, + Variant::List(l) => l.clone(), _ => panic!("Expected list"), }; // This will only add the first instance of 2... let added = l.set_add(&Var::mk_integer(2)).unwrap(); let added_v = match added.variant() { - Variant::List(l) => l, + Variant::List(l) => l.clone(), _ => panic!("Expected list"), }; // should still be [1, 2, 3] @@ -448,7 +442,7 @@ mod tests { ); // now add 4 - let added = l.set_add(&Var::mk_integer(4)).unwrap(); + let added = l.clone().set_add(&Var::mk_integer(4)).unwrap(); let added_v = match added.variant() { Variant::List(l) => l, _ => panic!("Expected list"), diff --git a/crates/values/src/var/map.rs b/crates/values/src/var/map.rs index 5f612382..ce854fdb 100644 --- a/crates/values/src/var/map.rs +++ b/crates/values/src/var/map.rs @@ -19,14 +19,14 @@ use crate::var::Associative; use crate::var::Error::{E_RANGE, E_TYPE}; use crate::var::{Error, VarType}; use bytes::Bytes; -use flexbuffers::{BuilderOptions, Reader, VectorReader}; +use flexbuffers::{BuilderOptions, VectorReader}; use std::cmp::Ordering; use std::hash::Hash; #[derive(Clone)] pub struct Map { // Reader must be boxed to avoid overfilling the stack. - pub reader: Box>, + pub reader: VectorReader, } impl Map { @@ -56,18 +56,15 @@ impl Map { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(buf)) } pub fn iter(&self) -> impl Iterator + '_ { (0..self.len()).map(move |i| { let k = self.reader.idx(i * 2); let v = self.reader.idx(i * 2 + 1); - let key = Variant::from_reader(k); - let value = Variant::from_reader(v); - (Var(key), Var(value)) + + (Var::from_reader(k), Var::from_reader(v)) }) } @@ -82,8 +79,7 @@ impl Map { while low <= high { let mid = (low + high) / 2; let k = self.reader.idx((mid * 2) as usize); - let k = Variant::from_reader(k); - let v = Var(k); + let v = Var::from_reader(k); match f(c, &v) { Ordering::Less => high = mid - 1, Ordering::Greater => low = mid + 1, @@ -134,9 +130,7 @@ impl Associative for Map { }; let v = self.reader.idx((pos * 2) + 1); - let v = Variant::from_reader(v); - let v = Var(v); - Ok(v) + Ok(Var::from_reader(v)) } fn index_in(&self, key: &Var, case_sensitive: bool) -> Result, Error> { @@ -144,8 +138,7 @@ impl Associative for Map { // Linear O(N) operation. for i in 0..self.len() { let v = self.reader.idx((i * 2) + 1); - let v = Variant::from_reader(v); - let v = Var(v); + let v = Var::from_reader(v); let matches = if case_sensitive { v.eq_case_sensitive(key) } else { @@ -198,17 +191,15 @@ impl Associative for Map { // Now scan forward to find the end. let mut new_vec = Vec::new(); - let to = to.variant(); for i in start..self.len() { let k = self.reader.idx(i * 2); - let k = Variant::from_reader(k); + let k = Var::from_reader(k); let order = k.cmp(to); if order == Ordering::Greater || order == Ordering::Equal { break; } let v = self.reader.idx(i * 2 + 1); - let v = Variant::from_reader(v); - new_vec.push((Var(k), Var(v))); + new_vec.push((k, Var::from_reader(v))); } Ok(Self::build_presorted(new_vec.iter())) @@ -249,8 +240,7 @@ impl Associative for Map { let mut keys = Vec::new(); for i in 0..self.len() { let k = self.reader.idx(i * 2); - let key = Variant::from_reader(k); - keys.push(Var(key)); + keys.push(Var::from_reader(k)) } keys } @@ -259,8 +249,7 @@ impl Associative for Map { let mut values = Vec::new(); for i in 0..self.len() { let v = self.reader.idx(i * 2 + 1); - let value = Variant::from_reader(v); - values.push(Var(value)); + values.push(Var::from_reader(v)) } values } @@ -364,7 +353,7 @@ mod tests { let key = Var::mk_str("a"); let value = m.index(&key, IndexMode::ZeroBased).unwrap(); match value.variant() { - Variant::Int(i) => assert_eq!(*i, 1), + Variant::Int(i) => assert_eq!(i, 1), _ => panic!("Expected integer"), } } @@ -442,7 +431,7 @@ mod tests { let key = Var::mk_str("b"); let value = m.index(&key, IndexMode::ZeroBased).unwrap(); match value.variant() { - Variant::Int(i) => assert_eq!(*i, 2), + Variant::Int(i) => assert_eq!(i, 2), _ => panic!("Expected integer"), } } @@ -467,7 +456,7 @@ mod tests { Variant::Map(m) => { let r = m.index(&Var::mk_str("b")).unwrap(); match r.variant() { - Variant::Int(i) => assert_eq!(*i, 42), + Variant::Int(i) => assert_eq!(i, 42), _ => panic!("Expected integer, got {:?}", r), } } @@ -487,7 +476,7 @@ mod tests { Variant::Map(m) => { let r = m.index(&Var::mk_str("d")).unwrap(); match r.variant() { - Variant::Int(i) => assert_eq!(*i, 42), + Variant::Int(i) => assert_eq!(i, 42), _ => panic!("Expected integer, got {:?}", r), } } diff --git a/crates/values/src/var/mod.rs b/crates/values/src/var/mod.rs index dd219464..4445927c 100644 --- a/crates/values/src/var/mod.rs +++ b/crates/values/src/var/mod.rs @@ -40,6 +40,7 @@ pub use list::List; pub use map::Map; pub use objid::Objid; use std::fmt::Debug; +use std::sync::Arc; pub use string::Str; use strum::FromRepr; pub use symbol::Symbol; @@ -104,13 +105,13 @@ impl IndexMode { } } -pub enum TypeClass<'a> { - Sequence(&'a dyn Sequence), - Associative(&'a dyn Associative), +pub enum TypeClass { + Sequence(Arc), + Associative(Arc), Scalar, } -impl<'a> TypeClass<'a> { +impl TypeClass { fn is_sequence(&self) -> bool { matches!(self, TypeClass::Sequence(_)) } diff --git a/crates/values/src/var/scalar.rs b/crates/values/src/var/scalar.rs index 9049814e..bb6d5fe2 100644 --- a/crates/values/src/var/scalar.rs +++ b/crates/values/src/var/scalar.rs @@ -28,13 +28,13 @@ macro_rules! binary_numeric_coercion_op { Ok(v_float(l.to_f64().unwrap().$op(r.to_f64().unwrap()))) } (Variant::Int(l), Variant::Int(r)) => { - paste! { l.[](*r).map(v_int).ok_or(E_INVARG) } + paste! { l.[](r).map(v_int).ok_or(E_INVARG) } } (Variant::Float(l), Variant::Int(r)) => { - Ok(v_float(l.to_f64().unwrap().$op(*r as f64))) + Ok(v_float(l.to_f64().unwrap().$op(r as f64))) } (Variant::Int(l), Variant::Float(r)) => { - Ok(v_float((*l as f64).$op(r.to_f64().unwrap()))) + Ok(v_float((l as f64).$op(r.to_f64().unwrap()))) } (_, _) => Ok(v_err(E_TYPE)), } @@ -52,10 +52,10 @@ impl Var { (Variant::Float(l), Variant::Float(r)) => { Ok(v_float(l.to_f64().unwrap() + r.to_f64().unwrap())) } - (Variant::Int(l), Variant::Int(r)) => l.checked_add(*r).map(v_int).ok_or(E_INVARG), - (Variant::Float(l), Variant::Int(r)) => Ok(v_float(l.to_f64().unwrap() + (*r as f64))), - (Variant::Int(l), Variant::Float(r)) => Ok(v_float(*l as f64 + r.to_f64().unwrap())), - (Variant::Str(s), Variant::Str(r)) => Ok(s.append(r)), + (Variant::Int(l), Variant::Int(r)) => l.checked_add(r).map(v_int).ok_or(E_INVARG), + (Variant::Float(l), Variant::Int(r)) => Ok(v_float(l.to_f64().unwrap() + (r as f64))), + (Variant::Int(l), Variant::Float(r)) => Ok(v_float(l as f64 + r.to_f64().unwrap())), + (Variant::Str(s), Variant::Str(r)) => Ok(s.append(&r)), (_, _) => Ok(v_err(E_TYPE)), } } @@ -70,23 +70,23 @@ impl Var { pub fn modulus(&self, v: &Self) -> Result { match (self.variant(), v.variant()) { - (Variant::Float(l), Variant::Float(r)) => Ok(v_float(*l % *r)), - (Variant::Int(l), Variant::Int(r)) => l.checked_rem(*r).map(v_int).ok_or(E_INVARG), - (Variant::Float(l), Variant::Int(r)) => Ok(v_float(l.to_f64().unwrap() % (*r as f64))), - (Variant::Int(l), Variant::Float(r)) => Ok(v_float(*l as f64 % (r.to_f64().unwrap()))), + (Variant::Float(l), Variant::Float(r)) => Ok(v_float(l % r)), + (Variant::Int(l), Variant::Int(r)) => l.checked_rem(r).map(v_int).ok_or(E_INVARG), + (Variant::Float(l), Variant::Int(r)) => Ok(v_float(l.to_f64().unwrap() % (r as f64))), + (Variant::Int(l), Variant::Float(r)) => Ok(v_float(l as f64 % (r.to_f64().unwrap()))), (_, _) => Ok(v_err(E_TYPE)), } } pub fn pow(&self, v: &Self) -> Result { match (self.variant(), v.variant()) { - (Variant::Float(l), Variant::Float(r)) => Ok(v_float(l.powf(*r))), + (Variant::Float(l), Variant::Float(r)) => Ok(v_float(l.powf(r))), (Variant::Int(l), Variant::Int(r)) => { - let r = u32::try_from(*r).map_err(|_| E_INVARG)?; + let r = u32::try_from(r).map_err(|_| E_INVARG)?; l.checked_pow(r).map(v_int).ok_or(E_INVARG) } - (Variant::Float(l), Variant::Int(r)) => Ok(v_float(l.powi(*r as i32))), - (Variant::Int(l), Variant::Float(r)) => Ok(v_float((*l as f64).powf(*r))), + (Variant::Float(l), Variant::Int(r)) => Ok(v_float(l.powi(r as i32))), + (Variant::Int(l), Variant::Float(r)) => Ok(v_float((l as f64).powf(r))), (_, _) => Ok(v_err(E_TYPE)), } } diff --git a/crates/values/src/var/storage.rs b/crates/values/src/var/storage.rs index a19c5c2e..5bb6af95 100644 --- a/crates/values/src/var/storage.rs +++ b/crates/values/src/var/storage.rs @@ -18,7 +18,7 @@ use bincode::enc::Encoder; use bincode::error::{DecodeError, EncodeError}; use bincode::{BorrowDecode, Decode, Encode}; use bytes::Bytes; -use flexbuffers::{Buffer, BuilderOptions}; +use flexbuffers::Buffer; use std::ops::{Deref, Range}; use std::str::Utf8Error; @@ -63,28 +63,22 @@ impl Deref for VarBuffer { impl Var { pub fn to_bytes(&self) -> Bytes { - let mut builder = flexbuffers::Builder::new(BuilderOptions::default()); - let mut vb = builder.start_vector(); - self.variant().push_to(&mut vb); - vb.end_vector(); - Bytes::from(builder.take_buffer()) + self.0 .0.clone() } } impl AsByteBuffer for Var { fn size_bytes(&self) -> usize { - let buf = self.to_bytes(); - buf.len() + self.0 .0.len() } fn with_byte_buffer R>(&self, mut f: F) -> Result { - let buf = self.to_bytes(); - Ok(f(buf.as_ref())) + let buf = self.0 .0.as_ref(); + Ok(f(buf)) } fn make_copy_as_vec(&self) -> Result, EncodingError> { - let buf = self.to_bytes(); - Ok(buf.to_vec()) + Ok(self.0 .0.to_vec()) } fn from_bytes(bytes: Bytes) -> Result diff --git a/crates/values/src/var/string.rs b/crates/values/src/var/string.rs index 93893751..ff6e0f0e 100644 --- a/crates/values/src/var/string.rs +++ b/crates/values/src/var/string.rs @@ -27,7 +27,7 @@ use std::hash::Hash; #[derive(Clone)] pub struct Str { // Reader must be boxed to avoid overfilling the stack. - pub(crate) reader: Box>, + pub(crate) reader: Reader, } impl Str { diff --git a/crates/values/src/var/var.rs b/crates/values/src/var/var.rs index 84b0b0f8..83cea0b4 100644 --- a/crates/values/src/var/var.rs +++ b/crates/values/src/var/var.rs @@ -25,22 +25,43 @@ use flexbuffers::{BuilderOptions, Reader}; use num_traits::ToPrimitive; use std::cmp::{min, Ordering}; use std::fmt::{Debug, Formatter}; +use std::hash::Hash; -#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] -pub struct Var(pub Variant); +#[derive(Clone)] +pub struct Var(pub VarBuffer); impl Debug for Var { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) + write!(f, "{:?}", self.variant()) } } impl Var { pub fn from_bytes(data: Bytes) -> Self { - let buf = VarBuffer(data); - let reader = Reader::get_root(buf).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(data)) + } + + pub fn from_reader(reader: Reader) -> Self { + // Unpack and then repack into a new buffer, since it seems flexbuffers won't let us pull the + // offsets out of the underlying buffer in the reader? + let mut builder = flexbuffers::Builder::new(BuilderOptions::empty()); + let mut vb = builder.start_vector(); + let variant = Variant::from_reader(reader); + variant.push_to(&mut vb); + vb.end_vector(); + let buf = builder.take_buffer(); + let buf = Bytes::from(buf); + Var(VarBuffer(buf)) + } + + pub fn from_variant(variant: Variant) -> Self { + let mut builder = flexbuffers::Builder::new(BuilderOptions::empty()); + let mut vb = builder.start_vector(); + variant.push_to(&mut vb); + vb.end_vector(); + let buf = builder.take_buffer(); + let buf = Bytes::from(buf); + Var(VarBuffer(buf)) } pub fn mk_integer(i: i64) -> Self { @@ -51,9 +72,7 @@ impl Var { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(buf)) } pub fn mk_none() -> Self { @@ -63,9 +82,7 @@ impl Var { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(buf)) } pub fn mk_str(s: &str) -> Self { @@ -76,9 +93,7 @@ impl Var { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(buf)) } pub fn mk_float(f: R64) -> Self { @@ -89,9 +104,7 @@ impl Var { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(buf)) } pub fn mk_error(e: Error) -> Self { @@ -102,9 +115,18 @@ impl Var { vb.end_vector(); let buf = builder.take_buffer(); let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) + Var(VarBuffer(buf)) + } + + pub fn mk_object(o: Objid) -> Self { + let mut builder = flexbuffers::Builder::new(BuilderOptions::empty()); + let mut vb = builder.start_vector(); + vb.push(VarType::TYPE_OBJ as u8); + vb.push(o.0); + vb.end_vector(); + let buf = builder.take_buffer(); + let buf = Bytes::from(buf); + Var(VarBuffer(buf)) } pub fn type_code(&self) -> VarType { @@ -132,29 +154,16 @@ impl Var { map::Map::build(pairs.iter()) } - pub fn mk_object(o: Objid) -> Self { - let mut builder = flexbuffers::Builder::new(BuilderOptions::empty()); - let mut vb = builder.start_vector(); - vb.push(VarType::TYPE_OBJ as u8); - vb.push(o.0); - vb.end_vector(); - let buf = builder.take_buffer(); - let buf = Bytes::from(buf); - let reader = Reader::get_root(VarBuffer(buf)).unwrap(); - let v = Variant::from_reader(reader); - Var(v) - } - - pub fn variant(&self) -> &Variant { - &self.0 + pub fn variant(&self) -> Variant { + Variant::from_reader(Reader::get_root(self.0.clone()).unwrap()) } pub fn is_true(&self) -> bool { match self.variant() { Variant::None => false, Variant::Obj(_) => false, - Variant::Int(i) => *i != 0, - Variant::Float(f) => *f != 0.0, + Variant::Int(i) => i != 0, + Variant::Float(f) => f != 0.0, Variant::List(l) => !l.reader.is_empty(), Variant::Str(s) => !s.as_string().is_empty(), Variant::Map(m) => !m.reader.is_empty(), @@ -172,7 +181,7 @@ impl Var { TypeClass::Sequence(s) => { let idx = match index.variant() { Variant::Int(i) => { - let i = index_mode.adjust_i64(*i); + let i = index_mode.adjust_i64(i); if i < 0 { return Err(E_RANGE); } @@ -205,7 +214,7 @@ impl Var { TypeClass::Sequence(s) => { let idx = match idx.variant() { Variant::Int(i) => { - let i = index_mode.adjust_i64(*i); + let i = index_mode.adjust_i64(i); if i < 0 { return Err(E_RANGE); @@ -229,7 +238,7 @@ impl Var { match self.type_class() { TypeClass::Sequence(s) => { let index = match index.variant() { - Variant::Int(i) => index_mode.adjust_i64(*i), + Variant::Int(i) => index_mode.adjust_i64(i), _ => return Err(E_INVARG), }; let index = if index < 0 { @@ -252,12 +261,12 @@ impl Var { match self.type_class() { TypeClass::Sequence(s) => { let from = match from.variant() { - Variant::Int(i) => index_mode.adjust_i64(*i), + Variant::Int(i) => index_mode.adjust_i64(i), _ => return Err(E_INVARG), }; let to = match to.variant() { - Variant::Int(i) => index_mode.adjust_i64(*i), + Variant::Int(i) => index_mode.adjust_i64(i), _ => return Err(E_INVARG), }; @@ -278,12 +287,12 @@ impl Var { match self.type_class() { TypeClass::Sequence(s) => { let from = match from.variant() { - Variant::Int(i) => index_mode.adjust_i64(*i), + Variant::Int(i) => index_mode.adjust_i64(i), _ => return Err(E_INVARG), }; let to = match to.variant() { - Variant::Int(i) => index_mode.adjust_i64(*i), + Variant::Int(i) => index_mode.adjust_i64(i), _ => return Err(E_INVARG), }; @@ -351,7 +360,7 @@ impl Var { match self.type_class() { TypeClass::Sequence(s) => { let index = match index.variant() { - Variant::Int(i) => index_mode.adjust_i64(*i), + Variant::Int(i) => index_mode.adjust_i64(i), _ => return Err(E_INVARG), }; @@ -388,14 +397,6 @@ impl Var { matches!(self.variant(), Variant::Str(_)) } - pub fn as_sequence(&self) -> Option<&dyn Sequence> { - match self.variant() { - Variant::List(l) => Some(l), - Variant::Str(s) => Some(s), - _ => None, - } - } - pub fn is_empty(&self) -> Result { match self.type_class() { TypeClass::Sequence(s) => Ok(s.is_empty()), @@ -564,6 +565,32 @@ impl From for Var { } } +impl PartialEq for Var { + fn eq(&self, other: &Self) -> bool { + self.variant() == other.variant() + } +} + +impl Eq for Var {} + +impl Ord for Var { + fn cmp(&self, other: &Self) -> Ordering { + self.variant().cmp(&other.variant()) + } +} + +impl PartialOrd for Var { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Hash for Var { + fn hash(&self, state: &mut H) { + self.variant().hash(state) + } +} + #[cfg(test)] mod tests { use crate::var::var::Var; @@ -574,7 +601,7 @@ mod tests { let i = Var::mk_integer(42); match i.variant() { - Variant::Int(i) => assert_eq!(*i, 42), + Variant::Int(i) => assert_eq!(i, 42), _ => panic!("Expected integer"), } } @@ -584,7 +611,7 @@ mod tests { let f = Var::mk_float(42.0.into()); match f.variant() { - Variant::Float(f) => assert_eq!(*f, 42.0), + Variant::Float(f) => assert_eq!(f, 42.0), _ => panic!("Expected float"), } } diff --git a/crates/values/src/var/variant.rs b/crates/values/src/var/variant.rs index 0dc14217..5df06ccd 100644 --- a/crates/values/src/var/variant.rs +++ b/crates/values/src/var/variant.rs @@ -23,6 +23,7 @@ use num_traits::ToPrimitive; use std::cmp::Ordering; use std::fmt::{Debug, Formatter}; use std::hash::{Hash, Hasher}; +use std::sync::Arc; /// Our series of types #[derive(Clone)] @@ -31,9 +32,9 @@ pub enum Variant { Obj(Objid), Int(i64), Float(f64), - List(List), - Str(string::Str), - Map(map::Map), + List(Arc), + Str(Arc), + Map(Arc), Err(Error), } @@ -147,9 +148,7 @@ impl Variant { } VarType::TYPE_STR => { let v = vec_iter.next().unwrap(); - Self::Str(string::Str { - reader: Box::new(v), - }) + Self::Str(Arc::new(string::Str { reader: v })) } VarType::TYPE_ERR => { // Error code encoded as u8 @@ -161,9 +160,7 @@ impl Variant { VarType::TYPE_LIST => { let v = vec_iter.next().unwrap(); let l = v.as_vector(); - Self::List(List { - reader: Box::new(l), - }) + Self::List(Arc::new(List { reader: l })) } VarType::TYPE_LABEL => { unimplemented!("Labels are not supported in actual values") @@ -171,9 +168,7 @@ impl Variant { VarType::TYPE_MAP => { let v = vec_iter.next().unwrap(); let m = v.as_vector(); - Self::Map(map::Map { - reader: Box::new(m), - }) + Self::Map(Arc::new(map::Map { reader: m })) } } } diff --git a/crates/web-host/src/host/mod.rs b/crates/web-host/src/host/mod.rs index ff999ff9..5e628851 100644 --- a/crates/web-host/src/host/mod.rs +++ b/crates/web-host/src/host/mod.rs @@ -43,10 +43,10 @@ pub fn var_as_json(v: &Var) -> serde_json::Value { Variant::None => serde_json::Value::Null, Variant::Str(s) => serde_json::Value::String(s.to_string()), Variant::Obj(o) => json!(Oid { oid: o.0 }), - Variant::Int(i) => serde_json::Value::Number(Number::from(*i)), - Variant::Float(f) => json!(*f), + Variant::Int(i) => serde_json::Value::Number(Number::from(i)), + Variant::Float(f) => json!(f), Variant::Err(e) => json!(Error { - error_code: (*e) as u8, + error_code: e as u8, error_name: e.name().to_string(), error_msg: e.message().to_string(), }),