Not necessarily.
A proposition about an implementation aspect of the language you're working in is testable in that language if a program in that language can produce output which is different based on whether or not that proposition is true. If the proposition isn't testable in that language, then it doesn't lie on the "all the way down" path which begins inside the language.
So you can have objects all the way down if you like. You just need something (such as an interpreter or compiler) that recognises your own self-consistent definition and swaps out pieces of it for a more reasonable implementation.
Admittedly it might be seen as a bit of a cheat, but I quite like it because it treats the mapping from a logically "pure" model to machine as an implementation issue. I'm working on a Ruby implementation and took the opposite model of having a lower level representation that I can "escape" into to implement the low level details, but I'm tempted to re-implement the small parts of the core that I can't do in pure Ruby to work the same way, as a experiment (though I better actually find some time to finish making it self-hosted first)
There has been several Lisp dialects (3-Lisp and T project) based on infinite tower of interpreters. You can build a language where the point where the rubber of abstraction hits the road of reality is nowhere to be found.
I'm not sure if it's really a counterexample, though. Does 3-Lisp claim that you can only interact with values by calling their methods, or something like that? For example, can you impersonate a cons cell?
> For that you need the internal representations of two different objects at once, not just their responses to a bunch of methods. If your language is objects all the way down, that's fundamentally impossible.
?
The machine instructions that operate on images are register based. You load the operand image into register(s) and invoke semantic (e.g. addition unsigned 32-bit), storing the result in registers.
Given that fact, your line of thinking would generalize to "there are no object oriented languages", since even getting the length of an array of Ducks must resolve to logical and/or mathematical ops at the machine level.
> .. special code detects ..
That sounds like an optimization to deal with the reality of contemporary hardware.
In fact, Smalltalk's VM has special code that detects when you try to add two small integers. That's similar to "abstract data types" in ML or "class-based encapsulation" in Java, as opposed to "object-based encapsulation" which is the cornerstone of Smalltalk.