|
Instruction::LoadSpecial { method } => { |
|
// Stack effect: 0 (replaces TOS with bound method) |
|
// Input: [..., obj] |
|
// Output: [..., bound_method] |
|
use crate::vm::PyMethod; |
|
use bytecode::SpecialMethod; |
|
|
|
let obj = self.pop_value(); |
|
let method_name = match method.get(arg) { |
|
SpecialMethod::Enter => identifier!(vm, __enter__), |
|
SpecialMethod::Exit => identifier!(vm, __exit__), |
|
SpecialMethod::AEnter => identifier!(vm, __aenter__), |
|
SpecialMethod::AExit => identifier!(vm, __aexit__), |
|
}; |
|
|
|
let bound = match vm.get_special_method(&obj, method_name)? { |
|
Some(PyMethod::Function { target, func }) => { |
|
// Create bound method: PyBoundMethod(object=target, function=func) |
|
crate::builtins::PyBoundMethod::new(target, func) |
|
.into_ref(&vm.ctx) |
|
.into() |
|
} |
|
Some(PyMethod::Attribute(bound)) => bound, |
|
None => { |
|
return Err(vm.new_type_error(format!( |
|
"'{}' object does not support the context manager protocol (missed {} method)", |
|
obj.class().name(), |
|
method_name |
|
))); |
|
} |
|
}; |
|
self.push_value(bound); |
|
Ok(None) |
|
} |
|
Instruction::LoadSpecial { method } => { |
|
// Stack effect: 0 (replaces TOS with bound method) |
|
// Input: [..., obj] |
|
// Output: [..., bound_method] |
|
use crate::vm::PyMethod; |
|
use bytecode::SpecialMethod; |
|
|
|
let obj = self.pop_value(); |
|
let method_name = match method.get(arg) { |
|
SpecialMethod::Enter => identifier!(vm, __enter__), |
|
SpecialMethod::Exit => identifier!(vm, __exit__), |
|
SpecialMethod::AEnter => identifier!(vm, __aenter__), |
|
SpecialMethod::AExit => identifier!(vm, __aexit__), |
|
}; |
|
|
|
let bound = match vm.get_special_method(&obj, method_name)? { |
|
Some(PyMethod::Function { target, func }) => { |
|
// Create bound method: PyBoundMethod(object=target, function=func) |
|
crate::builtins::PyBoundMethod::new(target, func) |
|
.into_ref(&vm.ctx) |
|
.into() |
|
} |
|
Some(PyMethod::Attribute(bound)) => bound, |
|
None => { |
|
return Err(vm.new_type_error(format!( |
|
"'{}' object does not support the context manager protocol (missing {} method)", |
|
obj.class().name(), |
|
method_name |
|
))); |
|
} |
|
}; |
|
self.push_value(bound); |
|
Ok(None) |
|
} |