dvander@29: /* vim: set ts=4 sw=4 tw=99 et: dvander@29: * dvander@29: * Copyright (C) 2012 David Anderson dvander@29: * dvander@29: * This file is part of JITCraft. dvander@29: * dvander@29: * JITCraft is free software: you can redistribute it and/or modify it under dvander@29: * the terms of the GNU General Public License as published by the Free dvander@29: * Software Foundation, either version 3 of the License, or (at your option) dvander@29: * any later version. dvander@29: * dvander@29: * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY dvander@29: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@29: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@29: * dvander@29: * You should have received a copy of the GNU General Public License along with dvander@29: * JITCraft. If not, see http://www.gnu.org/licenses/. dvander@29: */ dvander@64: #include dvander@64: #include dvander@29: #include "RootScopes.h" dvander@29: dvander@59: using namespace ke; dvander@29: dvander@29: RootScopeManager::RootScopeManager() dvander@29: : blocks_(&first_), dvander@29: first_(NULL), dvander@29: scope_(NULL) dvander@29: { dvander@29: } dvander@29: dvander@29: RootScopeManager::~RootScopeManager() dvander@29: { dvander@29: while (blocks_ != &first_) { dvander@29: Block *temp = blocks_; dvander@29: delete blocks_; dvander@29: blocks_ = temp; dvander@29: } dvander@29: } dvander@29: dvander@29: bool dvander@29: RootScopeManager::grow() dvander@29: { dvander@29: assert(blocks_->cur == blocks_->end); dvander@29: dvander@29: Block *block = new Block(blocks_); dvander@64: if (!block) { dvander@69: // We are not prepared for this. We'll start dishing out NULL-valued dvander@69: // ScopedRoots, and the engine generally assumes infallbility. Rather dvander@69: // then NULL check all sorts of nodes on parse trees, or add boolean dvander@69: // setters, for now we just abort. dvander@69: fprintf(stderr, "Unrecoverable error: could not allocate a local root scope. Aborting!\n"); dvander@64: abort(); dvander@29: return false; dvander@64: } dvander@29: dvander@29: blocks_ = block; dvander@29: return true; dvander@29: } dvander@29: dvander@29: void dvander@29: RootScopeManager::unwindSlow(Object **pos) dvander@29: { dvander@29: for (;;) { dvander@47: if (pos >= blocks_->objects && pos <= blocks_->end) dvander@29: break; dvander@29: assert(blocks_ != &first_); dvander@29: Block *temp = blocks_; dvander@29: delete blocks_; dvander@29: blocks_ = temp; dvander@29: } dvander@29: dvander@29: blocks_->cur = pos; dvander@29: } dvander@29: dvander@45: void dvander@45: RootScopeManager::accept(VirtualObjectVisitor *visitor) dvander@45: { dvander@45: Block *block = blocks_; dvander@45: while (block) { dvander@45: for (Object **ptr = block->objects; ptr < block->cur; ptr++) dvander@45: visitor->visit(ptr); dvander@45: block = block->prev; dvander@45: } dvander@45: }