diff --git a/vm/src/function.rs b/vm/src/function.rs index a505ad477..19495c772 100644 --- a/vm/src/function.rs +++ b/vm/src/function.rs @@ -34,6 +34,7 @@ macro_rules! into_func_args_from_tuple { where $($T: IntoPyObject,)* { + #[inline] fn into_args(self, vm: &VirtualMachine) -> FuncArgs { let ($($n,)*) = self; vec![$($n.into_pyobject(vm),)*].into() diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index a2d29e9f7..15f1484ec 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -477,6 +477,7 @@ impl Deref for PyRefExact { } } impl IntoPyObject for PyRefExact { + #[inline] fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { self.obj.into_object() } @@ -833,18 +834,21 @@ pub trait IntoPyObject { } impl IntoPyObject for PyRef { + #[inline] fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { self.into_object() } } impl IntoPyObject for PyCallable { + #[inline] fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { self.into_object() } } impl IntoPyObject for PyObjectRef { + #[inline] fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { self } @@ -856,6 +860,7 @@ impl IntoPyObject for T where T: PyValue + Sized, { + #[inline] fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { PyValue::into_object(self, vm) } @@ -896,26 +901,13 @@ cfg_if::cfg_if! { pub trait PyValue: fmt::Debug + PyThreadingConstraint + Sized + 'static { fn class(vm: &VirtualMachine) -> &PyTypeRef; + #[inline] fn into_object(self, vm: &VirtualMachine) -> PyObjectRef { self.into_ref(vm).into_object() } fn into_ref(self, vm: &VirtualMachine) -> PyRef { - self.into_ref_with_type_unchecked(Self::class(vm).clone(), vm) - } - - fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult> { - let class = Self::class(vm); - if cls.issubclass(class) { - Ok(self.into_ref_with_type_unchecked(cls, vm)) - } else { - let subtype = vm.to_str(cls.as_object())?; - let basetype = vm.to_str(cls.as_object())?; - Err(vm.new_type_error(format!("{} is not a subtype of {}", subtype, basetype))) - } - } - - fn into_ref_with_type_unchecked(self, cls: PyTypeRef, vm: &VirtualMachine) -> PyRef { + let cls = Self::class(vm).clone(); let dict = if cls.slots.flags.has_feature(PyTpFlags::HAS_DICT) { Some(vm.ctx.new_dict()) } else { @@ -923,6 +915,22 @@ pub trait PyValue: fmt::Debug + PyThreadingConstraint + Sized + 'static { }; PyRef::new_ref(self, cls, dict) } + + fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult> { + let exact_class = Self::class(vm); + if cls.issubclass(exact_class) { + let dict = if cls.slots.flags.has_feature(PyTpFlags::HAS_DICT) { + Some(vm.ctx.new_dict()) + } else { + None + }; + Ok(PyRef::new_ref(self, cls, dict)) + } else { + let subtype = vm.to_str(cls.as_object())?; + let basetype = vm.to_str(exact_class.as_object())?; + Err(vm.new_type_error(format!("{} is not a subtype of {}", subtype, basetype))) + } + } } pub trait PyObjectPayload: Any + fmt::Debug + PyThreadingConstraint + 'static {} diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 5e9b32203..b6e2f97db 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -971,38 +971,44 @@ impl VirtualMachine { } /// Call registered trace function. + #[inline] fn trace_event(&self, event: TraceEvent) -> PyResult<()> { if self.use_tracing.get() { - let trace_func = self.trace_func.borrow().clone(); - let profile_func = self.profile_func.borrow().clone(); - if self.is_none(&trace_func) && self.is_none(&profile_func) { - return Ok(()); - } + self._trace_event_inner(event) + } else { + Ok(()) + } + } + fn _trace_event_inner(&self, event: TraceEvent) -> PyResult<()> { + let trace_func = self.trace_func.borrow().clone(); + let profile_func = self.profile_func.borrow().clone(); + if self.is_none(&trace_func) && self.is_none(&profile_func) { + return Ok(()); + } - let frame_ref = self.current_frame(); - if frame_ref.is_none() { - return Ok(()); - } + let frame_ref = self.current_frame(); + if frame_ref.is_none() { + return Ok(()); + } - let frame = frame_ref.unwrap().as_object().clone(); - let event = self.ctx.new_str(event.to_string()); - let args = vec![frame, event, self.ctx.none()]; + let frame = frame_ref.unwrap().as_object().clone(); + let event = self.ctx.new_str(event.to_string()); + let args = vec![frame, event, self.ctx.none()]; - // temporarily disable tracing, during the call to the - // tracing function itself. - if !self.is_none(&trace_func) { - self.use_tracing.set(false); - let res = self.invoke(&trace_func, args.clone()); - self.use_tracing.set(true); - res?; - } + // temporarily disable tracing, during the call to the + // tracing function itself. + if !self.is_none(&trace_func) { + self.use_tracing.set(false); + let res = self.invoke(&trace_func, args.clone()); + self.use_tracing.set(true); + res?; + } - if !self.is_none(&profile_func) { - self.use_tracing.set(false); - let res = self.invoke(&profile_func, args); - self.use_tracing.set(true); - res?; - } + if !self.is_none(&profile_func) { + self.use_tracing.set(false); + let res = self.invoke(&profile_func, args); + self.use_tracing.set(true); + res?; } Ok(()) }