Added support for declaring empty-length arrays.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
21 #include "StringPool.h"
22 #include "TypeManager.h"
23 #include "GlobalRoots.h"
24 #include "AllocatorPolicies.h"
26 #include "Spaces-inl.h"
31 Zone *ke::SingleThreadedZone;
34 : stack_(thisFromCtor()),
35 heap_(thisFromCtor()),
40 hasPendingException_(false),
55 if (!stack_.initialize())
57 if (!heap_.initialize())
60 symbols_ = new StringPool(this);
61 if (!symbols_ || !symbols_->initialize())
64 globalRoots_ = new GlobalRoots(this);
65 if (!globalRoots_ || !globalRoots_->initialize())
68 maps_[MapKind_Meta] = heap_.metaMap();
69 if ((maps_[MapKind_Type] = allocateMap(MapKind_Type, sizeof(Map))) == NULL)
71 if ((maps_[MapKind_FixedArray] = allocateMap(MapKind_FixedArray, sizeof(Map))) == NULL)
73 if ((maps_[MapKind_ByteArray] = allocateMap(MapKind_ByteArray, sizeof(Map))) == NULL)
75 if ((maps_[MapKind_Code] = allocateMap(MapKind_Code, sizeof(Map))) == NULL)
77 if ((maps_[MapKind_Reference] = allocateMap(MapKind_Reference, sizeof(Map))) == NULL)
79 if ((maps_[MapKind_MetaArray] = allocateMap(MapKind_MetaArray, sizeof(Map))) == NULL)
81 if ((maps_[MapKind_MetaStruct] = allocateMap(MapKind_MetaStruct, sizeof(Map))) == NULL)
83 if ((maps_[MapKind_MetaEnvironment] = allocateMap(MapKind_MetaEnvironment, sizeof(Map))) == NULL)
85 if ((maps_[MapKind_Module] = allocateMap(MapKind_Module, sizeof(Map))) == NULL)
87 if ((maps_[MapKind_Function] = allocateMap(MapKind_Function, sizeof(Map))) == NULL)
89 if ((maps_[MapKind_String] = allocateMap(MapKind_String, sizeof(Map))) == NULL)
91 if ((maps_[MapKind_Native] = allocateMap(MapKind_Native, sizeof(Map))) == NULL)
93 if ((maps_[MapKind_Descriptor] = allocateMap(MapKind_Descriptor, sizeof(Map))) == NULL)
95 if ((maps_[MapKind_Box] = allocateMap(MapKind_Box, sizeof(Map))) == NULL)
97 if ((maps_[MapKind_FreeRegion] = allocateMap(MapKind_FreeRegion, sizeof(Map))) == NULL)
99 if ((maps_[MapKind_EnvironmentSlotDescriptorArray] =
100 allocateMap(MapKind_EnvironmentSlotDescriptorArray, sizeof(Map))) == NULL)
105 types_ = new TypeManager(this);
106 if (!types_ || !types_->initialize())
109 // Create the cached array maps for generic arrays. This is for the API
110 // version of Invoke(), which needs to make arrays very quickly from C++.
112 // Generic "cell" array (contents do not matter, just non-gc things).
113 Local<Type> type(this, types_->getPrimitive(PrimitiveType_Int32));
117 type = types_->newArray(type, Type::DYNAMIC_ARRAY_SIZE, false);
121 genericArrayMap_ = ArrayMap::New(this, type);
122 if (!genericArrayMap_)
125 type = types_->getPrimitive(PrimitiveType_Char);
129 type = types_->newArray(type, Type::DYNAMIC_ARRAY_SIZE, false);
133 charArrayMap_ = ArrayMap::New(this, type);
142 Zone::allocateMap(MapKind kind, size_t bytes, MapKind parent)
144 assert(maps_[parent]);
145 Map *map = heap_.allocateMap(kind, bytes);
148 map->init(maps_[parent]);
153 Zone::accept(VirtualObjectVisitor *visitor)
155 for (unsigned i = 0; i < MapKinds_Total; i++)
156 visitor->visit(maps_[i].address());
157 visitor->visit(charArrayMap_.address());
158 visitor->visit(genericArrayMap_.address());
159 types()->accept(visitor);
161 Local<Object> *local = lastLocalRoot_;
163 visitor->visit(local->address());
164 local = local->prev();
167 globalRoots_->accept(visitor);
168 rootScopes_.accept(visitor);
170 stack_.accept(visitor);
174 Zone::makeSymbol(const char *str, size_t length)
176 return symbols_->add(str, length);
180 Zone::makeSymbol(const char *str)
182 return makeSymbol(str, strlen(str));
186 Zone::hasPendingException()
188 return hasPendingException_;
192 Zone::reportOutOfMemory()
198 Zone::reportError(Message message, ...)
201 va_start(ap, message);
202 reportErrorVA(message, ap);
206 #if defined(_MSC_VER)
207 # define VA_COPY(to, from) to = from
209 # define VA_COPY(to, from) va_copy(to, from)
213 BuildErrorMessage(const char *format, va_list ap)
218 // We over-allocate and zero terminate ahead of time, since LIBCRT's
219 // version of vsnprintf is screwy.
221 char *buffer = (char *)calloc(size + 1, 1);
226 int r = vsnprintf(buffer, size, format, use);
228 if (r > -1 && size_t(r) < size)
231 #if defined(_MSC_VER)
236 size = size_t(r) + 1;
242 if ((buffer = (char *)calloc(size + 1, 1)) == NULL)
250 Zone::reportErrorVA(Message message, va_list ap)
252 char *report = BuildErrorMessage(Messages[message].format, ap);
259 // Reporters can re-enter. When we start having actual exception
260 // objects that can be caught and inspected, this code will have to
261 // save and restore the exception state.
262 reporter_->onUncaughtException(report);
265 hasPendingException_ = true;
271 Zone::beginCompilationErrors(const char *file)
274 reporter_->beginCompilationErrors(file);
278 Zone::reportCompilationError(Message message, unsigned line, unsigned col, va_list ap)
280 char *report = BuildErrorMessage(Messages[message].format, ap);
287 // Reporters can re-enter. When we start having actual exception
288 // objects that can be caught and inspected, this code will have to
289 // save and restore the exception state.
290 reporter_->reportCompilationError(report, line, col);
297 Zone::endCompilationErrors()
300 reporter_->endCompilationErrors();
304 Zone::installErrorReporter(Ke::IMessageReporter *reporter)
306 reporter_ = reporter;
310 ZoneAllocatorPolicy::reportOutOfMemory()
312 ZONE()->reportOutOfMemory();
316 ZoneAllocatorPolicy::reportAllocationOverflow()
318 ZONE()->reportError(Message_AllocationOverflow);
322 Zone::clearPendingException()
324 hasPendingException_ = false;