Remove use of setjmp/longjmp from libacc compiler.

It makes it harder to deal with memory allocation.

Also fix bug in the otcc-ansi.c test, where the wrong part of the
code buffer was being mprotected, so that if the code buffer happened
to be allocated across a page boundary, some code would no receive
execute permission.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index e0043ef..e7f95b0 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -11,7 +11,6 @@
 #include <ctype.h>
 #include <dlfcn.h>
 #include <errno.h>
-#include <setjmp.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -69,6 +68,7 @@
         char* pProgramBase;
         ErrorSink* mErrorSink;
         int mSize;
+        bool mOverflowed;
 
         void release() {
             if (pProgramBase != 0) {
@@ -77,13 +77,16 @@
             }
         }
 
-        void check(int n) {
+        bool check(int n) {
             int newSize = ind - pProgramBase + n;
-            if (newSize > mSize) {
+            bool overflow = newSize > mSize;
+            if (overflow && !mOverflowed) {
+                mOverflowed = true;
                 if (mErrorSink) {
                     mErrorSink->error("Code too large: %d bytes", newSize);
                 }
             }
+            return overflow;
         }
 
     public:
@@ -92,6 +95,7 @@
             ind = 0;
             mErrorSink = 0;
             mSize = 0;
+            mOverflowed = false;
         }
 
         ~CodeBuf() {
@@ -110,7 +114,9 @@
         }
 
         int o4(int n) {
-            check(4);
+            if(check(4)) {
+                return 0;
+            }
             intptr_t result = (intptr_t) ind;
             * (int*) ind = n;
             ind += 4;
@@ -121,7 +127,9 @@
          * Output a byte. Handles all values, 0..ff.
          */
         void ob(int n) {
-            check(1);
+            if(check(1)) {
+                return;
+            }
             *ind++ = n;
         }
 
@@ -1037,6 +1045,7 @@
         int decodeOp(int op) {
             if (op < 0 || op > OP_COUNT) {
                 error("Out-of-range operator: %d\n", op);
+                op = 0;
             }
             return operatorHelper[op];
         }
@@ -1363,8 +1372,6 @@
 
     String mErrorBuf;
 
-    jmp_buf mErrorRecoveryJumpBuf;
-
     String mPragmas;
     int mPragmaStringCount;
 
@@ -1430,6 +1437,7 @@
     void pdef(int t) {
         if (dstk - sym_stk >= ALLOC_SIZE) {
             error("Symbol table exhausted");
+            return;
         }
         *dstk++ = t;
     }
@@ -1475,7 +1483,6 @@
                 } else {
                     error("Unsupported preprocessor directive \"%s\"", last_id);
                 }
-
             }
             inp();
         }
@@ -1609,6 +1616,7 @@
         if (ch == '(') {
             delete pName;
             error("Defines with arguments not supported");
+            return;
         }
         while (isspace(ch)) {
             inp();
@@ -1669,7 +1677,6 @@
         mErrorBuf.printf("%ld: ", file->getLine());
         mErrorBuf.vprintf(fmt, ap);
         mErrorBuf.printf("\n");
-        longjmp(mErrorRecoveryJumpBuf, 1);
     }
 
     void skip(intptr_t c) {
@@ -2053,6 +2060,7 @@
     char* allocGlobalSpace(int bytes) {
         if (glo - pGlobalBase + bytes > ALLOC_SIZE) {
             error("Global space exhausted");
+            return NULL;
         }
         char* result = glo;
         glo += bytes;
@@ -2132,8 +2140,9 @@
         }
         if (pGen == NULL) {
             error("No code generator defined.");
+        } else {
+            pGen->setErrorSink(this);
         }
-        pGen->setErrorSink(this);
     }
 
 public:
@@ -2154,30 +2163,34 @@
 
     int compile(const char* text, size_t textLength) {
         int result;
-        if (! (result = setjmp(mErrorRecoveryJumpBuf))) {
-            cleanup();
-            clear();
-            codeBuf.init(ALLOC_SIZE);
-            setArchitecture(NULL);
-            if (!pGen) {
-                return -1;
+
+        cleanup();
+        clear();
+        codeBuf.init(ALLOC_SIZE);
+        setArchitecture(NULL);
+        if (!pGen) {
+            return -1;
+        }
+        pGen->init(&codeBuf);
+        file = new TextInputStream(text, textLength);
+        sym_stk = (char*) calloc(1, ALLOC_SIZE);
+        static const char* predefinedSymbols =
+            " int char void"
+            " if else while break return for"
+            " pragma define main ";
+        dstk = strcpy(sym_stk, predefinedSymbols)
+                + strlen(predefinedSymbols);
+        pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
+        glo = pGlobalBase;
+        pVarsBase = (char*) calloc(1, ALLOC_SIZE);
+        inp();
+        next();
+        globalDeclarations();
+        result = pGen->finishCompile();
+        if (result == 0) {
+            if (mErrorBuf.len()) {
+                result = -2;
             }
-            pGen->init(&codeBuf);
-            file = new TextInputStream(text, textLength);
-            sym_stk = (char*) calloc(1, ALLOC_SIZE);
-            static const char* predefinedSymbols =
-                " int char void"
-                " if else while break return for"
-                " pragma define main ";
-            dstk = strcpy(sym_stk, predefinedSymbols)
-                    + strlen(predefinedSymbols);
-            pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
-            glo = pGlobalBase;
-            pVarsBase = (char*) calloc(1, ALLOC_SIZE);
-            inp();
-            next();
-            globalDeclarations();
-            result = pGen->finishCompile();
         }
         return result;
     }
diff --git a/libacc/tests/data/otcc-ansi.c b/libacc/tests/data/otcc-ansi.c
index 5b75879..3ffad36 100644
--- a/libacc/tests/data/otcc-ansi.c
+++ b/libacc/tests/data/otcc-ansi.c
@@ -450,7 +450,7 @@
     o();
     ad();
     ab(0);
-    if (mprotect((ac + 592) & (~ 4095), (99999 + 4095) & (~ 4095), 7)) {
+    if (mprotect(ac & (~ 4095), (99999 + 4095) & (~ 4095), 7)) {
         printf("Mprotect failed. %d\n", errno);
         return -1;
     }