From ad543f242ef2e300cbda21f0f9b26355c79fd3a2 Mon Sep 17 00:00:00 2001 From: youknowdot Date: Sun, 18 Oct 2026 16:35:04 +0900 Subject: [PATCH] Avoid duplicate AST initialization and eager import locals allocation Let type.__call__ own AST initialization, matching CPython generic allocation, and inspect existing frame locals without materializing them for lazy policy checks. Assisted-by: OpenAI Codex:model version unavailable --- crates/vm/src/lazy_import.rs | 13 ++++++++----- crates/vm/src/stdlib/_ast/python.rs | 6 +----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/crates/vm/src/lazy_import.rs b/crates/vm/src/lazy_import.rs index a6b37398ab3..2f713953def 100644 --- a/crates/vm/src/lazy_import.rs +++ b/crates/vm/src/lazy_import.rs @@ -232,13 +232,16 @@ pub(crate) fn init_type(ctx: &'static Context) { PyLazyImport::extend_class(ctx, ctx.types.lazy_import_type); } -pub(crate) fn is_module_level(vm: &VirtualMachine) -> bool { +pub(crate) fn is_module_level() -> bool { let frame = frame::current_thread_iframe(); if frame.is_null() { return false; } let frame = unsafe { &*frame }; - frame.globals().as_object().is(frame.locals.as_object(vm)) + frame + .locals + .get() + .is_some_and(|locals| frame.globals().as_object().is(locals.obj())) } fn optional_item( @@ -266,9 +269,9 @@ pub(crate) fn import_name( let explicit = policy & 1 != 0; let globals = vm.current_globals(); let mut lazy = - explicit || (vm.state.lazy_imports.all.load(Ordering::Acquire) && is_module_level(vm)); + explicit || (vm.state.lazy_imports.all.load(Ordering::Acquire) && is_module_level()); if !lazy - && is_module_level(vm) + && is_module_level() && let Some(names) = optional_item( globals.as_object(), vm.ctx.intern_str("__lazy_modules__"), @@ -316,7 +319,7 @@ pub(crate) fn create( vm: &VirtualMachine, ) -> PyResult { let absolute = crate::import::absolute_import_name(name, Some(globals), level, vm)?; - if !is_module_level(vm) { + if !is_module_level() { return Err(vm.new_exception_msg( vm.ctx.exceptions.syntax_error.to_owned(), "'lazy import' is only allowed at module level".into(), diff --git a/crates/vm/src/stdlib/_ast/python.rs b/crates/vm/src/stdlib/_ast/python.rs index 7e146a5d479..6e4d8df4099 100644 --- a/crates/vm/src/stdlib/_ast/python.rs +++ b/crates/vm/src/stdlib/_ast/python.rs @@ -293,7 +293,7 @@ pub(crate) mod _ast { impl Constructor for NodeAst { type Args = FuncArgs; - fn slot_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult { + fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { // Keep _instance for parser-internal shared operator/context nodes, // but match CPython's public constructor behavior by allocating a // fresh object for Python-level ast.Load()/ast.Add()/... calls. @@ -311,10 +311,6 @@ pub(crate) mod _ast { }; let zelf = vm.ctx.new_base_object(cls, dict); - // type.__call__ does not invoke slot_init after slot_new - // for types with a custom slot_new, so we must call it here. - Self::slot_init(&zelf, args, vm)?; - Ok(zelf) }