开发者

Polymorphism Without Indirect Jumps?

When I learned MIPS assembly a few months ago, a question popped into my head that I forgot to ask then, so I thought I'd ask it now:

Is it possible to implement polymorphism without indirect jump instructions? If so, how?

(Indirect jumps are the "jump register" instructions, e.g. jr $t0 in MIPS or jmp EAX in x86.)

One such solution I came up with is self-modifying cod开发者_如何学编程e, but I'm curious as to whether polymorphism (and so OOP) would be possible by any other means.


The simplest answer to your question would be to write your program (and possible assembler) in such a way that all method calls can be resolved at runtime thus negating the need for a lookup table. I'm going to assume you're talking about passing a subclass to a function that was designed for a superclass and it is therefore impossible to implement this optimization.

Eliminating the lookup, I think, is outside the scope of your question so I'm going to suggest replacements for the jmp <reg> instruction (sorry, I only know x86).

  • You can execute a call <mem> on a memory address (isn't this how you would do it using a lookup table?)
  • You can execute a call <reg> on a register (not entirely different from the jmp , but does answer your question)
  • You can jmp <mem> if you wanted, but that's not all that different from jmp <reg>

All of these are possible and solve your problem, but are all alike. I guess this illustrates my confusion on why you would want to do what you're asking. You have to have some way to choose which method to call (the vtable) and some way to transfer execution to the method (using jmp or call).

The only other possible way to do this would be to fiddle with the register that is used to point to the next command in the execution chain (EIP in x86). Whether you can or should is another question. I suppose if you were intimately knowledgeable of the architecture and weren't worried about it changing you could do that.


Yes

You may want to consider changing your question however

Consider this C++ code where Derived is obviously polymorphic (yes, I didn't delete the object):

class Base
{
    public: int foo(){ return 1; }
};

class Derived: public Base
{
    public: int foo(){ return 2; };
};

int main()
{
    Base* b = new Derived();

    return b->foo();    //Returns 1
}

The assembly generated by gcc is

main:
.LFB2:
    pushq   %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe   %rbp, 0
    subq    $48, %rsp
    .seh_stackalloc 48
    .seh_endprologue
    call    __main
    movl    $1, %ecx
    call    _Znwm
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rcx
    call    _ZN4Base3fooEv
    addq    $48, %rsp
    popq    %rbp
    ret

As you can see there is no indirect jump/call.

That's because polymorphism is not the point here (though it is necessary), virtual methods are.

Then the answer becames

No

If by indirect jump/call you means every technique that use a runtime value for computing the target of the jump/call (so including things like ret, call [], call reg, jr, jalr).

Consider this source

#include <iostream>

class Base
{
    public: virtual int foo(){ return 1; }
};

class Derived: public Base
{
    public: int foo(){ return 2; };
};

class Derived2: public Base
{
    public: int foo(){ return 3; };
};



int main()
{
    int a;
    Base* b = 0; //don't remember the header for std::nullptr right now...

    std::cin >> a;

    if (a > 241)
        b = new Derived();
    else 
        b = new Derived2();

    return b->foo();    //Returns what?
}

The result depends on the user input, an archetypal runtime value, so must be the called routine and no static address would do.

Note that in this case the compiler could use a jump toward calls with static address (as either Derived2::foo or Derived::foo is called) but this is not in general possible (you may have multiple object files without the source, you may have an aliasing pointer, the pointer b could be set by an external library, and so on).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜