Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac0e95eb authored by Jack Palevich's avatar Jack Palevich
Browse files

Improve ACC error reporting.

Now return an error code and an error message, rather than just
printing to stderr or calling exit().

Check to see we don't exceed our code size.
parent 653f42da
Loading
Loading
Loading
Loading
+116 −46
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@


#include <ctype.h>
#include <ctype.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdint.h>
#include <stdio.h>
#include <stdio.h>
@@ -45,10 +46,24 @@


namespace acc {
namespace acc {


class Compiler {
class ErrorSink {
public:
    void error(const char *fmt, ...) {
        va_list ap;
        va_start(ap, fmt);
        verror(fmt, ap);
        va_end(ap);
    }

    virtual void verror(const char* fmt, va_list ap) = 0;
};

class Compiler : public ErrorSink {
    class CodeBuf {
    class CodeBuf {
        char* ind; // Output code pointer
        char* ind; // Output code pointer
        char* pProgramBase;
        char* pProgramBase;
        ErrorSink* mErrorSink;
        int mSize;


        void release() {
        void release() {
            if (pProgramBase != 0) {
            if (pProgramBase != 0) {
@@ -57,10 +72,21 @@ class Compiler {
            }
            }
        }
        }


        void check(int n) {
            int newSize = ind - pProgramBase + n;
            if (newSize > mSize) {
                if (mErrorSink) {
                    mErrorSink->error("Code too large: %d bytes", newSize);
                }
            }
        }

    public:
    public:
        CodeBuf() {
        CodeBuf() {
            pProgramBase = 0;
            pProgramBase = 0;
            ind = 0;
            ind = 0;
            mErrorSink = 0;
            mSize = 0;
        }
        }


        ~CodeBuf() {
        ~CodeBuf() {
@@ -69,11 +95,17 @@ class Compiler {


        void init(int size) {
        void init(int size) {
            release();
            release();
            mSize = size;
            pProgramBase = (char*) calloc(1, size);
            pProgramBase = (char*) calloc(1, size);
            ind = pProgramBase;
            ind = pProgramBase;
        }
        }


        void setErrorSink(ErrorSink* pErrorSink) {
            mErrorSink = pErrorSink;
        }

        int o4(int n) {
        int o4(int n) {
            check(4);
            intptr_t result = (intptr_t) ind;
            intptr_t result = (intptr_t) ind;
            * (int*) ind = n;
            * (int*) ind = n;
            ind += 4;
            ind += 4;
@@ -84,6 +116,7 @@ class Compiler {
         * Output a byte. Handles all values, 0..ff.
         * Output a byte. Handles all values, 0..ff.
         */
         */
        void ob(int n) {
        void ob(int n) {
            check(1);
            *ind++ = n;
            *ind++ = n;
        }
        }


@@ -123,11 +156,22 @@ class Compiler {


    class CodeGenerator {
    class CodeGenerator {
    public:
    public:
        CodeGenerator() {}
        CodeGenerator() {
            mErrorSink = 0;
            pCodeBuf = 0;
        }
        virtual ~CodeGenerator() {}
        virtual ~CodeGenerator() {}


        virtual void init(CodeBuf* pCodeBuf) {
        virtual void init(CodeBuf* pCodeBuf) {
            this->pCodeBuf = pCodeBuf;
            this->pCodeBuf = pCodeBuf;
            pCodeBuf->setErrorSink(mErrorSink);
        }

        void setErrorSink(ErrorSink* pErrorSink) {
            mErrorSink = pErrorSink;
            if (pCodeBuf) {
                pCodeBuf->setErrorSink(mErrorSink);
            }
        }
        }


        /* Emit a function prolog.
        /* Emit a function prolog.
@@ -323,8 +367,16 @@ class Compiler {
        intptr_t getSize() {
        intptr_t getSize() {
            return pCodeBuf->getSize();
            return pCodeBuf->getSize();
        }
        }

        void error(const char* fmt,...) {
            va_list ap;
            va_start(ap, fmt);
            mErrorSink->verror(fmt, ap);
            va_end(ap);
        }
    private:
    private:
        CodeBuf* pCodeBuf;
        CodeBuf* pCodeBuf;
        ErrorSink* mErrorSink;
    };
    };


#ifdef PROVIDE_ARM_CODEGEN
#ifdef PROVIDE_ARM_CODEGEN
@@ -643,7 +695,7 @@ class Compiler {
        virtual void callRelative(int t) {
        virtual void callRelative(int t) {
            LOG_API("callRelative(%d);\n", t);
            LOG_API("callRelative(%d);\n", t);
            int abs = t + getPC() + jumpOffset();
            int abs = t + getPC() + jumpOffset();
            fprintf(stderr, "abs=%d (0x%08x)\n", abs, abs);
            LOG_API("abs=%d (0x%08x)\n", abs, abs);
            if (t >= - (1 << 25) && t < (1 << 25)) {
            if (t >= - (1 << 25) && t < (1 << 25)) {
                o4(0xEB000000 | encodeAddress(t));
                o4(0xEB000000 | encodeAddress(t));
            } else {
            } else {
@@ -791,14 +843,6 @@ class Compiler {
        static int runtime_MOD(int a, int b) {
        static int runtime_MOD(int a, int b) {
            return b % a;
            return b % a;
        }
        }

        void error(const char* fmt,...) {
            va_list ap;
            va_start(ap, fmt);
            vfprintf(stderr, fmt, ap);
            va_end(ap);
            exit(12);
        }
    };
    };


#endif // PROVIDE_ARM_CODEGEN
#endif // PROVIDE_ARM_CODEGEN
@@ -980,8 +1024,7 @@ class Compiler {


        int decodeOp(int op) {
        int decodeOp(int op) {
            if (op < 0 || op > OP_COUNT) {
            if (op < 0 || op > OP_COUNT) {
                fprintf(stderr, "Out-of-range operator: %d\n", op);
                error("Out-of-range operator: %d\n", op);
                exit(1);
            }
            }
            return operatorHelper[op];
            return operatorHelper[op];
        }
        }
@@ -1048,6 +1091,10 @@ class Compiler {
    CodeBuf codeBuf;
    CodeBuf codeBuf;
    CodeGenerator* pGen;
    CodeGenerator* pGen;


    static const int ERROR_BUF_SIZE = 512;
    char mErrorBuf[ERROR_BUF_SIZE];
    jmp_buf mErrorRecoveryJumpBuf;

    static const int ALLOC_SIZE = 99999;
    static const int ALLOC_SIZE = 99999;


    /* depends on the init string */
    /* depends on the init string */
@@ -1265,15 +1312,24 @@ class Compiler {
#endif
#endif
    }
    }


    void error(const char *fmt, ...) {
        va_list ap;


        va_start(ap, fmt);
    virtual void verror(const char* fmt, va_list ap) {
        fprintf(stderr, "%ld: ", file->tell());
        char* pBase = mErrorBuf;
        vfprintf(stderr, fmt, ap);
        int bytesLeft = sizeof(mErrorBuf);
        fprintf(stderr, "\n");
        int bytesAdded = snprintf(pBase, bytesLeft, "%ld: ", file->tell());
        va_end(ap);
        bytesLeft -= bytesAdded;
        exit(1);
        pBase += bytesAdded;
        if (bytesLeft > 0) {
            bytesAdded = vsnprintf(pBase, bytesLeft, fmt, ap);
            bytesLeft -= bytesAdded;
            pBase += bytesAdded;
        }
        if (bytesLeft > 0) {
            bytesAdded = snprintf(pBase, bytesLeft, "\n");
            bytesLeft -= bytesAdded;
            pBase += bytesAdded;
        }
        longjmp(mErrorRecoveryJumpBuf, 1);
    }
    }


    void skip(intptr_t c) {
    void skip(intptr_t c) {
@@ -1606,6 +1662,7 @@ class Compiler {
        pGlobalBase = 0;
        pGlobalBase = 0;
        pVarsBase = 0;
        pVarsBase = 0;
        pGen = 0;
        pGen = 0;
        mErrorBuf[0] = 0;
    }
    }


    void setArchitecture(const char* architecture) {
    void setArchitecture(const char* architecture) {
@@ -1624,7 +1681,7 @@ class Compiler {
            }
            }
#endif
#endif
            if (!pGen ) {
            if (!pGen ) {
                fprintf(stderr, "Unknown architecture %s\n", architecture);
                error("Unknown architecture %s\n", architecture);
            }
            }
        }
        }


@@ -1636,8 +1693,9 @@ class Compiler {
#endif
#endif
        }
        }
        if (pGen == NULL) {
        if (pGen == NULL) {
            fprintf(stderr, "No code generator defined.\n");
            error("No code generator defined.");
        }
        }
        pGen->setErrorSink(this);
    }
    }


public:
public:
@@ -1657,6 +1715,8 @@ public:
    }
    }


    int compile(const char* text, size_t textLength) {
    int compile(const char* text, size_t textLength) {
        int result;
        if (! (result = setjmp(mErrorRecoveryJumpBuf))) {
            cleanup();
            cleanup();
            clear();
            clear();
            codeBuf.init(ALLOC_SIZE);
            codeBuf.init(ALLOC_SIZE);
@@ -1677,7 +1737,8 @@ public:
            next();
            next();
            decl(0);
            decl(0);
            pGen->finishCompile();
            pGen->finishCompile();
        return 0;
        }
        return result;
    }
    }


    int run(int argc, char** argv) {
    int run(int argc, char** argv) {
@@ -1731,6 +1792,10 @@ public:
        return NULL;
        return NULL;
    }
    }


    char* getErrorMessage() {
        return mErrorBuf;
    }

};
};


const char* Compiler::operatorChars =
const char* Compiler::operatorChars =
@@ -1881,11 +1946,16 @@ void accGetScriptInfoLog(ACCscript* script,
    ACCsizei maxLength,
    ACCsizei maxLength,
    ACCsizei * length,
    ACCsizei * length,
    ACCchar * infoLog) {
    ACCchar * infoLog) {
    char* message = script->compiler.getErrorMessage();
    int messageLength = strlen(message) + 1;
    if (length) {
    if (length) {
        *length = 0;
        *length = messageLength;
    }
    }
    if (maxLength > 0 && infoLog) {
    if (infoLog && maxLength > 0) {
        *infoLog = 0;
        int trimmedLength = maxLength < messageLength ?
                maxLength : messageLength;
        memcpy(infoLog, message, trimmedLength);
        infoLog[trimmedLength] = 0;
    }
    }
}
}


+2 −0
Original line number Original line Diff line number Diff line
void foo;
+10 −2
Original line number Original line Diff line number Diff line
@@ -81,12 +81,18 @@ int main(int argc, char** argv) {
    delete[] text;
    delete[] text;


    accCompileScript(script);
    accCompileScript(script);

    int result = accGetError(script);
    MainPtr mainPointer = 0;
    MainPtr mainPointer = 0;
    if (result != 0) {
        char buf[1024];
        accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
        fprintf(stderr, "%ss", buf);
        goto exit;
    }


    accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
    accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);


    int result = accGetError(script);
    result = accGetError(script);
    if (result == ACC_NO_ERROR) {
    if (result == ACC_NO_ERROR) {
        fprintf(stderr, "Executing compiled code:\n");
        fprintf(stderr, "Executing compiled code:\n");
        int codeArgc = argc - i + 1;
        int codeArgc = argc - i + 1;
@@ -96,6 +102,8 @@ int main(int argc, char** argv) {
        fprintf(stderr, "result: %d\n", result);
        fprintf(stderr, "result: %d\n", result);
    }
    }


exit:

    accDeleteScript(script);
    accDeleteScript(script);


    return result;
    return result;