I have observed a behaviour regarding __proto__ which seems weird to me: when changing __proto__ to various objects it behaves as expected, but onc
The issue is that __proto__ in Firefox is an actual property on Object.prototype implemented with getter/setter functions. So when you set the __proto__ of o to null, you wiped out the entire prototype chain, which included the __proto__ property.
Now when you assign to __proto__, you're just assigning a new, normal property that doesn't have the desired behavior directly to the o object.
So in order to get the functionality of __proto__, you'll need to go to Object.prototype, and borrow the .set method of the __proto__ property, and use .call to allow it to operate on the o object.
Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set.call(o, p);
So this invokes the set function of Object.prototype.__proto__ using .call so that the o becomes the this value of set, and p is the value being set. This will make __proto__ operate on o as though it was a property of o, allowing it to set the internal [[Prototype]] property.
Note that this is only tested in Firefox.