From 5f25c5deb031f944a6ac92275f245ab8fc5d377c Mon Sep 17 00:00:00 2001 From: Ashy Date: Wed, 19 Oct 2022 11:39:58 +0100 Subject: [PATCH 1/6] Update vm.rs Made it possible to fallback to Protocol::INDEX_GET on failure to find a field via Protocol::GET, same applies to Protocol::INDEX_SET and Protocol::SET --- crates/rune/src/runtime/vm.rs | 79 ++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index c0e1439ca..677b4def3 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -533,6 +533,28 @@ impl Vm { Ok(CallResult::Unsupported(target)) } + /// Helper to call a field function which has been prechecked to exist. + #[inline(always)] + fn call_field_fn_prechecked( + &mut self, + target: Value, + handler: &Arc Result<(), VmError> + Send + Sync>, + args: A, + ) -> Result, VmError> + where + A: Args, + { + let count = args.count(); + let full_count = count + 1; + + self.stack.push(target); + args.into_stack(&mut self.stack)?; + + handler(&mut self.stack, full_count)?; + + Ok(CallResult::Ok(())) + } + /// Helper to call an index function. #[inline(always)] fn call_index_fn( @@ -927,10 +949,26 @@ impl Vm { } target => { let hash = index.hash(); - - return Ok(match self.call_field_fn(Protocol::GET, target, hash, ())? { - CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), - CallResult::Unsupported(target) => CallResult::Unsupported(target), + let type_hash = + Hash::field_fn(Protocol::GET, target.type_hash()?, hash.into_type_hash()); + return Ok(if let Some(handler) = self.context.function(type_hash) { + match unsafe { + //Unsafe block required to avoid cloning index if it isn't needed. + (self as *const Self as *mut Self) + .as_mut() + .unwrap_unchecked() + } + .call_field_fn_prechecked(target, handler, ())? + { + CallResult::Ok(()) => return Ok(CallResult::Ok(self.stack.pop()?)), + CallResult::Unsupported(target) => CallResult::Unsupported(target), + } + } else { + let index = index.clone(); + match self.call_instance_fn(target, Protocol::INDEX_GET, (index,))? { + CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), + CallResult::Unsupported(target) => CallResult::Unsupported(target), + } }); } } @@ -984,14 +1022,33 @@ impl Vm { } target => { let hash = field.hash(); - - match self.call_field_fn(Protocol::SET, target, hash, (value,))? { - CallResult::Ok(()) => { - self.stack.pop()?; - CallResult::Ok(()) + let type_hash = + Hash::field_fn(Protocol::SET, target.type_hash()?, hash.into_type_hash()); + return Ok(if let Some(handler) = self.context.function(type_hash) { + match unsafe { + //Unsafe block required to avoid cloning index if it isn't needed. + (self as *const Self as *mut Self) + .as_mut() + .unwrap_unchecked() } - result => result, - } + .call_field_fn_prechecked(target, handler, (value,))? + { + CallResult::Ok(()) => { + self.stack.pop()?; + return Ok(CallResult::Ok(())); + } + CallResult::Unsupported(target) => CallResult::Unsupported(target), + } + } else { + let index = field.clone(); + match self.call_instance_fn(target, Protocol::INDEX_SET, (index, value))? { + CallResult::Ok(()) => { + self.stack.pop()?; + CallResult::Ok(()) + } + CallResult::Unsupported(target) => CallResult::Unsupported(target), + } + }); } }) } From 58c5471d14c4d55f65f626bb7616e7503a7ce29e Mon Sep 17 00:00:00 2001 From: Ashy Date: Wed, 19 Oct 2022 16:31:33 +0100 Subject: [PATCH 2/6] Applied the requested changes. --- crates/rune/src/runtime/vm.rs | 86 +++++++++-------------------------- 1 file changed, 21 insertions(+), 65 deletions(-) diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index 677b4def3..ddab70d77 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -533,28 +533,6 @@ impl Vm { Ok(CallResult::Unsupported(target)) } - /// Helper to call a field function which has been prechecked to exist. - #[inline(always)] - fn call_field_fn_prechecked( - &mut self, - target: Value, - handler: &Arc Result<(), VmError> + Send + Sync>, - args: A, - ) -> Result, VmError> - where - A: Args, - { - let count = args.count(); - let full_count = count + 1; - - self.stack.push(target); - args.into_stack(&mut self.stack)?; - - handler(&mut self.stack, full_count)?; - - Ok(CallResult::Ok(())) - } - /// Helper to call an index function. #[inline(always)] fn call_index_fn( @@ -948,28 +926,16 @@ impl Vm { } } target => { - let hash = index.hash(); - let type_hash = - Hash::field_fn(Protocol::GET, target.type_hash()?, hash.into_type_hash()); - return Ok(if let Some(handler) = self.context.function(type_hash) { - match unsafe { - //Unsafe block required to avoid cloning index if it isn't needed. - (self as *const Self as *mut Self) - .as_mut() - .unwrap_unchecked() - } - .call_field_fn_prechecked(target, handler, ())? + let index = index.clone(); + return Ok(match self + .call_field_fn(Protocol::GET, target, index.hash(), ())? { CallResult::Ok(()) => return Ok(CallResult::Ok(self.stack.pop()?)), - CallResult::Unsupported(target) => CallResult::Unsupported(target), - } - } else { - let index = index.clone(); - match self.call_instance_fn(target, Protocol::INDEX_GET, (index,))? { - CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), - CallResult::Unsupported(target) => CallResult::Unsupported(target), - } - }); + CallResult::Unsupported(target) => match self.call_instance_fn(target, Protocol::INDEX_GET, (index,))? { + CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), + CallResult::Unsupported(target) => CallResult::Unsupported(target), + }, + }); } } @@ -1021,34 +987,24 @@ impl Vm { })); } target => { - let hash = field.hash(); - let type_hash = - Hash::field_fn(Protocol::SET, target.type_hash()?, hash.into_type_hash()); - return Ok(if let Some(handler) = self.context.function(type_hash) { - match unsafe { - //Unsafe block required to avoid cloning index if it isn't needed. - (self as *const Self as *mut Self) - .as_mut() - .unwrap_unchecked() - } - .call_field_fn_prechecked(target, handler, (value,))? + let index = field.clone(); + return Ok(match self + .call_field_fn(Protocol::SET, target, index.hash(), (value.clone(),))? { - CallResult::Ok(()) => { - self.stack.pop()?; - return Ok(CallResult::Ok(())); - } - CallResult::Unsupported(target) => CallResult::Unsupported(target), - } - } else { - let index = field.clone(); - match self.call_instance_fn(target, Protocol::INDEX_SET, (index, value))? { CallResult::Ok(()) => { self.stack.pop()?; CallResult::Ok(()) } - CallResult::Unsupported(target) => CallResult::Unsupported(target), - } - }); + CallResult::Unsupported(target) => { + match self.call_instance_fn(target, Protocol::INDEX_SET, (index, value))? { + CallResult::Ok(()) => { + self.stack.pop()?; + CallResult::Ok(()) + } + CallResult::Unsupported(target) => CallResult::Unsupported(target), + } + } + }); } }) } From d5d3325154a65b3b374901326fedcf812853f501 Mon Sep 17 00:00:00 2001 From: Ashy Date: Wed, 19 Oct 2022 17:18:51 +0100 Subject: [PATCH 3/6] Separated fallback Separated fallback into its own protocol. --- crates/rune/src/runtime/protocol.rs | 12 ++++++++++++ crates/rune/src/runtime/vm.rs | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/rune/src/runtime/protocol.rs b/crates/rune/src/runtime/protocol.rs index 8912a8a83..4c86591db 100644 --- a/crates/rune/src/runtime/protocol.rs +++ b/crates/rune/src/runtime/protocol.rs @@ -81,6 +81,18 @@ impl Protocol { hash: Hash::new(0x418f5becbf885806), }; + /// The function to access a field by name when Protocol::GET fails. + pub const GET_FALLBACK: Protocol = Protocol { + name: "get_fallback", + hash: Hash::new(0x6dda58b140dfeaf9), + }; + + /// The function to set a field by name when Protocol::SET fails. + pub const SET_FALLBACK: Protocol = Protocol { + name: "set_fallback", + hash: Hash::new(0xbe28c02896ca0b64), + }; + /// The function to access a field. pub const GET: Protocol = Protocol { name: "get", diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index ddab70d77..d9748ce44 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -931,7 +931,7 @@ impl Vm { .call_field_fn(Protocol::GET, target, index.hash(), ())? { CallResult::Ok(()) => return Ok(CallResult::Ok(self.stack.pop()?)), - CallResult::Unsupported(target) => match self.call_instance_fn(target, Protocol::INDEX_GET, (index,))? { + CallResult::Unsupported(target) => match self.call_instance_fn(target, Protocol::GET_FALLBACK, (index,))? { CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), CallResult::Unsupported(target) => CallResult::Unsupported(target), }, @@ -996,7 +996,7 @@ impl Vm { CallResult::Ok(()) } CallResult::Unsupported(target) => { - match self.call_instance_fn(target, Protocol::INDEX_SET, (index, value))? { + match self.call_instance_fn(target, Protocol::SET_FALLBACK, (index, value))? { CallResult::Ok(()) => { self.stack.pop()?; CallResult::Ok(()) From e08900d31bb0472ca1a4b9134700dd8f41e2ca6d Mon Sep 17 00:00:00 2001 From: Ashy Date: Wed, 19 Oct 2022 17:21:20 +0100 Subject: [PATCH 4/6] Renamed fallback protocols Renamed fallback protocols to be consistent with INDEX_GET and INDEX_SET. --- crates/rune/src/runtime/protocol.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rune/src/runtime/protocol.rs b/crates/rune/src/runtime/protocol.rs index 4c86591db..915ae7bcf 100644 --- a/crates/rune/src/runtime/protocol.rs +++ b/crates/rune/src/runtime/protocol.rs @@ -82,14 +82,14 @@ impl Protocol { }; /// The function to access a field by name when Protocol::GET fails. - pub const GET_FALLBACK: Protocol = Protocol { - name: "get_fallback", + pub const FALLBACK_GET: Protocol = Protocol { + name: "fallback_get", hash: Hash::new(0x6dda58b140dfeaf9), }; /// The function to set a field by name when Protocol::SET fails. - pub const SET_FALLBACK: Protocol = Protocol { - name: "set_fallback", + pub const FALLBACK_SET: Protocol = Protocol { + name: "fallback_set", hash: Hash::new(0xbe28c02896ca0b64), }; From 2f617dd01aba20bf47a1d8f65a0a9ef585510dfd Mon Sep 17 00:00:00 2001 From: Ashy Date: Wed, 19 Oct 2022 17:24:49 +0100 Subject: [PATCH 5/6] Update vm.rs --- crates/rune/src/runtime/vm.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index d9748ce44..79528e46d 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -931,7 +931,7 @@ impl Vm { .call_field_fn(Protocol::GET, target, index.hash(), ())? { CallResult::Ok(()) => return Ok(CallResult::Ok(self.stack.pop()?)), - CallResult::Unsupported(target) => match self.call_instance_fn(target, Protocol::GET_FALLBACK, (index,))? { + CallResult::Unsupported(target) => match self.call_instance_fn(target, Protocol::FALLBACK_GET, (index,))? { CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), CallResult::Unsupported(target) => CallResult::Unsupported(target), }, @@ -996,7 +996,7 @@ impl Vm { CallResult::Ok(()) } CallResult::Unsupported(target) => { - match self.call_instance_fn(target, Protocol::SET_FALLBACK, (index, value))? { + match self.call_instance_fn(target, Protocol::FALLBACK_SET, (index, value))? { CallResult::Ok(()) => { self.stack.pop()?; CallResult::Ok(()) From 70ca8e0c668053781e858a93880d1ff228e0602e Mon Sep 17 00:00:00 2001 From: Ashy Date: Wed, 19 Oct 2022 19:57:22 +0100 Subject: [PATCH 6/6] Fixed formatting. --- crates/rune/src/runtime/vm.rs | 37 +++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index 79528e46d..bb721d080 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -927,15 +927,17 @@ impl Vm { } target => { let index = index.clone(); - return Ok(match self - .call_field_fn(Protocol::GET, target, index.hash(), ())? - { + return Ok( + match self.call_field_fn(Protocol::GET, target, index.hash(), ())? { CallResult::Ok(()) => return Ok(CallResult::Ok(self.stack.pop()?)), - CallResult::Unsupported(target) => match self.call_instance_fn(target, Protocol::FALLBACK_GET, (index,))? { - CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), - CallResult::Unsupported(target) => CallResult::Unsupported(target), - }, - }); + CallResult::Unsupported(target) => { + match self.call_instance_fn(target, Protocol::FALLBACK_GET, (index,))? { + CallResult::Ok(()) => CallResult::Ok(self.stack.pop()?), + CallResult::Unsupported(target) => CallResult::Unsupported(target), + } + } + }, + ); } } @@ -988,15 +990,23 @@ impl Vm { } target => { let index = field.clone(); - return Ok(match self - .call_field_fn(Protocol::SET, target, index.hash(), (value.clone(),))? - { + return Ok( + match self.call_field_fn( + Protocol::SET, + target, + index.hash(), + (value.clone(),), + )? { CallResult::Ok(()) => { self.stack.pop()?; CallResult::Ok(()) } CallResult::Unsupported(target) => { - match self.call_instance_fn(target, Protocol::FALLBACK_SET, (index, value))? { + match self.call_instance_fn( + target, + Protocol::FALLBACK_SET, + (index, value), + )? { CallResult::Ok(()) => { self.stack.pop()?; CallResult::Ok(()) @@ -1004,7 +1014,8 @@ impl Vm { CallResult::Unsupported(target) => CallResult::Unsupported(target), } } - }); + }, + ); } }) }