jitcraft/Zone.cpp
changeset 69 dfce0539a77d
parent 68 b40b0e18a918
child 85 06a0015b6a5c
     1.1 --- a/jitcraft/Zone.cpp	Tue Jul 10 02:11:13 2012 -0700
     1.2 +++ b/jitcraft/Zone.cpp	Wed Jul 11 01:12:54 2012 -0700
     1.3 @@ -16,6 +16,7 @@
     1.4   * You should have received a copy of the GNU General Public License along with
     1.5   * JITCraft. If not, see http://www.gnu.org/licenses/.
     1.6   */
     1.7 +#include <stdlib.h>
     1.8  #include "Zone.h"
     1.9  #include "StringPool.h"
    1.10  #include "TypeManager.h"
    1.11 @@ -28,11 +29,14 @@
    1.12  Zone *ke::SingleThreadedZone;
    1.13  
    1.14  Zone::Zone()
    1.15 -  : heap_(this),
    1.16 +  : stack_(thisFromCtor()),
    1.17 +    heap_(thisFromCtor()),
    1.18      types_(NULL),
    1.19      symbols_(NULL),
    1.20      globalRoots_(NULL),
    1.21 -    lastLocalRoot_(NULL)
    1.22 +    lastLocalRoot_(NULL),
    1.23 +    hasPendingException_(false),
    1.24 +    reporter_(NULL)
    1.25  {
    1.26  }
    1.27  
    1.28 @@ -164,16 +168,138 @@
    1.29      return makeSymbol(str, strlen(str));
    1.30  }
    1.31  
    1.32 +bool
    1.33 +Zone::hasPendingException()
    1.34 +{
    1.35 +    return hasPendingException_;
    1.36 +}
    1.37 +
    1.38 +void
    1.39 +Zone::reportOutOfMemory()
    1.40 +{
    1.41 +    
    1.42 +}
    1.43 +
    1.44 +void
    1.45 +Zone::reportError(Message message, ...)
    1.46 +{
    1.47 +    va_list ap;
    1.48 +    va_start(ap, message);
    1.49 +    reportErrorVA(message, ap);
    1.50 +    va_end(ap);
    1.51 +}
    1.52 +
    1.53 +#if defined(_MSC_VER)
    1.54 +# define VA_COPY(to, from)  to = from
    1.55 +#else
    1.56 +# define VA_COPY(to, from)  va_copy(to, from)
    1.57 +#endif
    1.58 +
    1.59 +static char *
    1.60 +BuildErrorMessage(const char *format, va_list ap)
    1.61 +{
    1.62 +    va_list use;
    1.63 +    VA_COPY(use, ap);
    1.64 +
    1.65 +    // We over-allocate and zero terminate ahead of time, since LIBCRT's
    1.66 +    // version of vsnprintf is screwy.
    1.67 +    size_t size = 255;
    1.68 +    char *buffer = (char *)calloc(size + 1, 1);
    1.69 +    if (!buffer)
    1.70 +        return NULL;
    1.71 +
    1.72 +    for (;;) {
    1.73 +        int r = vsnprintf(buffer, size, format, use);
    1.74 +
    1.75 +        if (r > -1 && size_t(r) < size)
    1.76 +            return buffer;
    1.77 +       
    1.78 +#if defined(_MSC_VER)
    1.79 +        if (r < 0)
    1.80 +            size *= 2;
    1.81 +#else
    1.82 +        if (r > -1)
    1.83 +            size = size_t(r) + 1;
    1.84 +        else
    1.85 +            size *= 2;
    1.86 +#endif
    1.87 +
    1.88 +        free(buffer);
    1.89 +        if ((buffer = (char *)calloc(size + 1, 1)) == NULL)
    1.90 +            return NULL;
    1.91 +
    1.92 +        VA_COPY(use, ap);
    1.93 +    }
    1.94 +}
    1.95 +
    1.96 +void
    1.97 +Zone::reportErrorVA(Message message, va_list ap)
    1.98 +{
    1.99 +    char *report = BuildErrorMessage(Messages[message].format, ap);
   1.100 +    if (!report) {
   1.101 +        reportOutOfMemory();
   1.102 +        return;
   1.103 +    }
   1.104 +
   1.105 +    if (reporter_) {
   1.106 +        // Reporters can re-enter. When we start having actual exception
   1.107 +        // objects that can be caught and inspected, this code will have to
   1.108 +        // save and restore the exception state.
   1.109 +        reporter_->onUncaughtException(report);
   1.110 +    }
   1.111 +
   1.112 +    hasPendingException_ = true;
   1.113 +
   1.114 +    free(report);
   1.115 +}
   1.116 +
   1.117 +void
   1.118 +Zone::beginCompilationErrors(const char *file)
   1.119 +{
   1.120 +    if (reporter_)
   1.121 +        reporter_->beginCompilationErrors(file);
   1.122 +}
   1.123 +
   1.124 +void
   1.125 +Zone::reportCompilationError(Message message, unsigned line, unsigned col, va_list ap)
   1.126 +{
   1.127 +    char *report = BuildErrorMessage(Messages[message].format, ap);
   1.128 +    if (!report) {
   1.129 +        reportOutOfMemory();
   1.130 +        return;
   1.131 +    }
   1.132 +
   1.133 +    if (reporter_) {
   1.134 +        // Reporters can re-enter. When we start having actual exception
   1.135 +        // objects that can be caught and inspected, this code will have to
   1.136 +        // save and restore the exception state.
   1.137 +        reporter_->reportCompilationError(report, line, col);
   1.138 +    }
   1.139 +
   1.140 +    free(report);
   1.141 +}
   1.142 +
   1.143 +void
   1.144 +Zone::endCompilationErrors()
   1.145 +{
   1.146 +    if (reporter_)
   1.147 +        reporter_->endCompilationErrors();
   1.148 +}
   1.149 +
   1.150 +void
   1.151 +Zone::installErrorReporter(Ke::IMessageReporter *reporter)
   1.152 +{
   1.153 +    reporter_ = reporter;
   1.154 +}
   1.155 +
   1.156  void
   1.157  ZoneAllocatorPolicy::reportOutOfMemory()
   1.158  {
   1.159 -    // :TODO: report
   1.160 -    assert(false);
   1.161 +    ZONE()->reportOutOfMemory();
   1.162  }
   1.163  
   1.164  void
   1.165  ZoneAllocatorPolicy::reportAllocationOverflow()
   1.166  {
   1.167 -    // :TODO: report
   1.168 -    assert(false);
   1.169 +    ZONE()->reportError(Message_AllocationOverflow);
   1.170  }