SetAttr: writes to instance `__dict__`; rejects modules and builtins. */
(recv_h: u32, name: &str, args: &[Val])
| 105 | |
| 106 | /* SetAttr: writes to instance `__dict__`; rejects modules and builtins. */ |
| 107 | fn dispatch_set_attr(recv_h: u32, name: &str, args: &[Val]) -> Result<Val, VmErr> { |
| 108 | if args.len() != 1 { |
| 109 | return Err(VmErr::TypeMsg(s!("set_attr expects exactly 1 value, got ", int args.len() as i64))); |
| 110 | } |
| 111 | let value = args[0]; |
| 112 | with_recv("edge_op set_attr: invalid receiver handle", recv_h, |vm, recv| { |
| 113 | if !recv.is_heap() { |
| 114 | return Err(VmErr::Type("cannot set attribute on this type")); |
| 115 | } |
| 116 | if let HeapObj::Instance(_cls, attrs) = vm.heap.get(recv) { |
| 117 | let attrs = attrs.clone(); |
| 118 | let key = vm.heap.alloc(HeapObj::Str(name.to_string()))?; |
| 119 | attrs.borrow_mut().insert(key, value, &vm.heap); |
| 120 | return Ok(Val::none()); |
| 121 | } |
| 122 | Err(VmErr::Type("cannot set attribute on this type")) |
| 123 | }) |
| 124 | } |
| 125 | |
| 126 | /* GetItem: built-in indexing only, FFI has no bytecode frame to drive instance `__getitem__` dispatch. */ |
| 127 | fn dispatch_get_item(recv_h: u32, args: &[Val]) -> Result<Val, VmErr> { |