Project

General

Profile

Simple way to directly access the Code::Emitter::Context methods

Added by Rochus Keller about 1 year ago

I would actually prefer to use the original Emitter::Context implementation instead of my Emitter2 copy. But this class resists access by all means.

I have made a subclass like

class MyEmitter : public Code::Emitter
{
public:
    MyEmitter(Diagnostics& d, StringPool& sp, Charset& c, Code::Platform& p):
        Code::Emitter(d,sp,c,p),ctx(*this,s) {}

    class Context : public Code::Emitter::Context
    {
    public:
        Context(const Emitter & e, Code::Sections & s):Emitter::Context(e,s) {}

        using Smop = Emitter::Context::SmartOperand;
        using Label = Emitter::Context::Label;

        Smop Pop (const Code::Operand& target) { return Emitter::Context::Pop(target); }

    };

    Code::Sections s;
    Context ctx;
};

in the hope to access its methods (like e.g. Pop) via the ctx member; but it doesn't let me. Is there an easy way to access these methods from within codegen.cpp without implementing an adapter method for each one I would like to use? So far the easiest solution was to duplicate everything in the Emitter2 class, but this is not a satisfactory solution.


Replies (3)

RE: Simple way to directly access the Code::Emitter::Context methods - Added by Rochus Keller about 1 year ago

If I change the "protected:" in Code::Emitter::Context to "public:", I get access to the methods via this adapter:

class MyEmitter : public Code::Emitter
{
public:
    MyEmitter(Diagnostics& d, StringPool& sp, Charset& c, Code::Platform& p):
        Code::Emitter(d,sp,c,p),ctx(*this,s) {}

    using Smop = Emitter::Context::SmartOperand;
    using Label = Emitter::Context::Label;
    using Context = Code::Emitter::Context;

    Code::Sections s;
    Context ctx;
};

But I still need a using declaration for each type; but I can live with that.

RE: Simple way to directly access the Code::Emitter::Context methods - Added by Florian Negele about 1 year ago

The basic idea is to actually move all of your global variables and functions into the derived Context class. This way you don't have to use the e-> prefix. Then add an Emit function to your MyEmitter class which instantiates this Context class and calls its codegen function. This makes the emitter automatically thread-safe and reusable. See the FALSE emitter for a simple example of this design.

RE: Simple way to directly access the Code::Emitter::Context methods - Added by Rochus Keller about 1 year ago

Ok, thanks. I though that you might have provisioned a modern modern C++ trick which I didn't know ;-)
Inheriting is an option of course, but in general I prefer to reference instead of inheriting APIs; your view might be different because your compilers are essentially part of the same code base as the backends; for me though the backends are just a library which I want to use.
Therefore I go with making the emittercontext protected members public. I also want to avoid refactoring codegen.cpp too much, because of effort and likelihood to add new bugs, but also to keep the code as similar as possible to the original codegen. Chibicc is generally not thread safe, so I don't care about multithreading.

    (1-3/3)