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 }